Reputation: 1064
I'm a bit confused why this piece of code produces 2 records in a list (acts appropriately):
var historiesToRemove = new List<WorkHistory>();
foreach (var history in this.WorkHistories)
{
if (history.Tool.Equals(item))
{
historiesToRemove.Add(history);
}
}
While this piece of code produces an empty list:
var historiesToRemove = this.WorkHistories.Where(history => history.Tool.Equals(item)).ToList();
Any ideas why could this happen?
REASON:
I didn't properly implement IDbSet's IQueryable properties. This made my LINQ act wrong.
Upvotes: 2
Views: 1036
Reputation: 532445
This is just a guess, but I would say that you've probably provided a definition of equality that is different than that used by the LINQ translation in EF. In EF I believe that it uses property equality, whereas you might only be checking that the IDs are the same. I suggest that you explicitly encode the definition of equality that you want to check in your LINQ statement. The reason that your equality definition works in the first case is that enumerating the IDbSet brings it into memory and thus invokes your version of Equals rather than the LINQ-to-EF translation of Equals.
var historiesToRemove = this.WorkHistories.Where( h => h.Tool.ID == tool.ID )
.ToList();
Upvotes: 1
Reputation: 21881
IDbSet
that you mention in a comment is part of the entity framework so your 2 pieces of code are not equivalent. The LINQ is an expression tree that gets converted to SQL by EF whereas the first bit of code retreieves the entire table from the database and executes the loop in memory. Profile the database to find out what SQL is executing in the database and this should give you an idea why the linq does not do what you want.
Upvotes: 1
Reputation: 32418
Edit: Just saw you have ToList
on the end of the query, so the below does not apply.
Read up on closures and LINQ. Probably 'item' is changing before you run the query.
Example problem code:
var filter = "Compare";
var query = from m in typeof(String).GetMethods()
where m.Name.Contains(filter)
select new { m.Name, ParameterCount = m.GetParameters().Length };
filter = "IndexOf";
foreach (var item in query)
Console.WriteLine(item);
Upvotes: 1