Linq query built in foreach loop always takes parameter value from last iteration
You're reusing the same variable (key
) in your lambda expression.
See my article on anonymous methods for more details, and there are a number of related SO questions too:
- LINQ to SQL bug (or very strange feature)...
- Local variables with delegates
- C# captured variable in a loop
- C# gotcha answer
- Building a LINQ query programmatically without local variables tricking me
The simple fix is to copy the variable first:
List<string> keys = FillKeys()
foreach (string key in keys){
string copy = key;
q = q.Where(c => c.Company.Name.Contains(copy));
}
Linq query built in foreach loop always takes parameter value from last iteration
You're reusing the same variable (key
) in your lambda expression.
See my article on anonymous methods for more details, and there are a number of related SO questions too:
- LINQ to SQL bug (or very strange feature)...
- Local variables with delegates
- C# captured variable in a loop
- C# gotcha answer
- Building a LINQ query programmatically without local variables tricking me
The simple fix is to copy the variable first:
List<string> keys = FillKeys()
foreach (string key in keys){
string copy = key;
q = q.Where(c => c.Company.Name.Contains(copy));
}
Building a LINQ query programmatically without local variables tricking me
(Edited for clarity.)
The problem is the foreach loop, and the fact that the "a" variable is being captured and then changed each time. Here's a modification which will work, by effectively introducing a "new" variable for each iteration of the loop, and capturing that new variable.
foreach (Attribute a in requiredAttributes)
{
Attribute copy = a;
result = result.Where(p => p.Attributes.Contains(copy));
}
Omer's solution is a cleaner one if you can use it, but this may help if your real code is actually more complicated :)
EDIT: There's more about the issue in this closures article - scroll down to "Comparing capture strategies: complexity vs power".
Foreach Iteration Null
Calling the value of a non existing attribute will cause a nullreference because the node simply doesn't exist.
child.Attribute("ows_ContentType").Value
throws an exception by calling the value of the missing element.
use this instead:
child.Attribute("ows_ContentType") != null
implemented:
IEnumerable<XElement> result = from child in root.Descendants(xns + "row")
where child.Attribute("ows_ContentType") != null && child.Attribute("ows_ContentType").Value == "Folder"
select child;
Building query in a loop with entity framework strange behaviour
Thanks Equiso, I didn't find the question you refered to. So this is an exact duplicate of Linq query built in foreach loop always takes parameter value from last iteration.
How do you get the index of the current iteration of a foreach loop?
The foreach
is for iterating over collections that implement IEnumerable
. It does this by calling GetEnumerator
on the collection, which will return an Enumerator
.
This Enumerator has a method and a property:
MoveNext()
Current
Current
returns the object that Enumerator is currently on, MoveNext
updates Current
to the next object.
The concept of an index is foreign to the concept of enumeration, and cannot be done.
Because of that, most collections are able to be traversed using an indexer and the for loop construct.
I greatly prefer using a for loop in this situation compared to tracking the index with a local variable.
Can I use linq to achieve the same thing this foreach loop does?
Similar to some existing answers, but doing the projection in the query, to make the Sum
call a lot simpler:
var sum = (from fee in loan.Items.Fees
where fee.Classification == 806
select fee.SomeValueToSum).Sum();
Can all 'for' loops be replaced with a LINQ statement?
Sure. Heck, you can replace arithmetic with LINQ queries:
http://blogs.msdn.com/ericlippert/archive/2009/12/07/query-transformations-are-syntactic.aspx
But you shouldn't.
The purpose of a query expression is to represent a query operation. The purpose of a "for" loop is to iterate over a particular statement so as to have its side-effects executed multiple times. Those are frequently very different. I encourage replacing loops whose purpose is merely to query data with higher-level constructs that more clearly query the data. I strongly discourage replacing side-effect-generating code with query comprehensions, though doing so is possible.
Related Topics
How to Get the Value of Private Field Using Reflection
Parsing Performance (If, Tryparse, Try-Catch)
Finding a Subsequence in Longer Sequence
How to Create a Button That Can Send Keys to a Conrol Without Losing Focus - Virtual Keyboard
Entity Framework. Delete All Rows in Table
: ? Operators Instead of If|Else
Draw on the Screen Without a Form
Read Binary File into a Struct
How to Include Other Files to the Output Directory in C# Upon Build
How to Send a File and Form Data with Httpclient in C#
C# Regular Expressions, String Between Single Quotes
Selectively Use Default JSON Converter
C# Dll Cannot Affect Value of a Number Passed by Reference from a Vb6 Application