score:6
i have only glanced at your question, but i am 90% sure that you should read the first section of on lambdas, capture, and mutability (which includes links to 5 similar so questions) and all will become clear.
the basic gist of it is that the variable ofilter
in your example has been captured in the closure by reference and not by value. that means that once the loop finishes iterating, the variable's reference is to the last one, so the value as evaluated at lambda execution time is the final one as well.
the cure is to insert a new variable inside the foreach
loop whose scope is only that iteration rather than the whole loop:
foreach(var ofilter in filterlist)
{
var filter = ofilter; // add this
switch (ofilter.column) // this doesn't have to change, but can for consistency
{
case filtertype.supplier:
query = query.where(p => p.supplierid == filter.id); // use `filter` here
break;
now each closure is over a different filter
variable that is declared anew inside of each loop, and your code will run as expected.
score:-3
the problem is that you're not appending to the query, you're replacing it each time through the foreach statement.
you want something like the predicatebuilder - http://www.albahari.com/nutshell/predicatebuilder.aspx
score:0
i think this is the clearest explanation i've ever seen: http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx:
basically, the problem arises because we specify that the foreach loop is a syntactic sugar for
{
ienumerator<int> e = ((ienumerable<int>)values).getenumerator();
try
{
int m; // outside the actual loop
while(e.movenext())
{
m = (int)(int)e.current;
funcs.add(()=>m);
}
}
finally
{
if (e != null) ((idisposable)e).dispose();
}
}
if we specified that the expansion was
try
{
while(e.movenext())
{
int m; // inside
m = (int)(int)e.current;
funcs.add(()=>m);
}
then the code would behave as expected.
score:2
working as designed. the issue you are confronting is the clash between lexical closure and mutable variables.
what you probably want to do is
foreach(var ofilter in filterlist)
{
var o = ofilter;
switch (o.column)
{
case filtertype.supplier:
query = query.where(p => p.supplierid == o.id);
break;
case filtertype.category:
query = query.where(p => p.categoryid == o.id);
break;
default:
break;
}
}
when compiled to il, the variable ofilter
is declared once and used multiply. what you need is a variable declared separately for each use of that variable within a closure, which is what o
is now there for.
while you're at it, get rid of that bastardized hungarian notation :p.
Source: stackoverflow.com
Related Query
- LINQ to SQL bug (or very strange feature) when using IQueryable, foreach, and multiple Where
- Is a full list returned first and then filtered when using linq to sql to filter data from a database or just the filtered list?
- How can I check the number of calls to the database in LINQ query when using .NET Core and Code First?
- Optimise and speed up very slow Linq / SQL code
- LINQ to SQL using GROUP BY and COUNT(DISTINCT)
- Why does C# compiler create private DisplayClass when using LINQ method Any() and how can I avoid it?
- Differences between IEquatable<T>, IEqualityComparer<T>, and overriding .Equals() when using LINQ on a custom object collection?
- Steps for a beginner to run very basic linq to sql query using Linqpad
- Linq to SQL using group By, and order by count
- Is ToList required when using foreach with LINQ to Entities
- LINQ to SQL *compiled* queries and when they execute
- SQL Query to LINQ syntax using not exist and join
- LINQ to SQL - Compile error when extending data context with partial class and methods
- LINQ isn't calling Dispose on my IEnumerator when using Union and Select, expected behavior or bug?
- Entity Framework Linq Query to List - Error when using contains: Only primitive types, enumeration types and entity types are supported
- Why is IQueryable twice as fast than IEnumerable when using Linq To Objects
- How to reuse a linq expression for 'Where' when using multiple source tables
- Good way to time SQL queries when using Linq to SQL
- Avoiding code repetition when using LINQ
- What are the difference between .Select, .Any, and .Count when using LINQ
- Duplicate rows when using orderby, Skip() and Take() with LINQ
- How to construct IQueryable query using Linq when I just need count without reading all documents in Document-Db database?
- LINQ to SQL join 3 tables and select multiple columns and also using Sum
- How can I code an outer join using LINQ and EF6?
- When to expect IEnumerable and when to expect IQueryable from a Linq query
- What are the prerequisites for using SQL and LINQ with my winforms application in C#?
- Strange collation issue using LINQ to SQL
- Differences between VB TryCast and C# "as" operator when using LINQ
- why the sql query is different on that linq query when run on c# and on vb.net?
- How does Linq to SQL perform when using List.Contain()?
More Query from same tag
- .Except<T> is throwing an Exception
- Using reflection throws error in EF Core 3
- Why take just one? Linq to XML C#
- find missing column name and row no of datacolum in linq
- Linq OrderBy string
- Parsing a string from a textfile and using LINQ
- How to mapping value with identifier and variable value in C#
- Linq to XML Error
- Exception when trying to create/use an inner transaction
- Does C# 7 allow to deconstruct tuples in linq expressions
- Linq parser issue?
- C# Linq to group by object properties
- Need better way to sum up data
- Return data from multiple tables using LINQ Method Syntax
- Enumerating updated lists
- Where to find translated Linq to Entity query to Sql
- how does skip and take really work?
- query convert from sql to linq
- Linq to get distinct subdirectories from list of paths
- LinQ query doesn't order
- C# Dedupe a List with a List and Combine the List
- LINQ update value in parent rows from ther child rows
- Copy Properties of one object to another object
- Is it possible to use Intersect on complex arrays in C#?
- Selecting max number from a list of string in LINQ?
- LINQ query gone wrong
- Group By List<Item>
- How to validate LINQ queryable without database
- Convert / Cast IEnumerable to IEnumerable<T>
- How to load two SQL Tables into dataset and how to bind it to ListView?