score:1

Accepted answer

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.

score:1

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);

score:1

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();

Related Articles