Question

OK, this is doing my head in - I'm not even sure how to search for this.

Here is the first part of my function:

var rules = context.Rules.Include(r => r.CreatedBy).Include(r => r.ModifiedBy);

IUserManager um = GetUserManager();
var currentUser = um.GetCurrent();

Can someone tell me why this works:

return rules.Where(delegate(Rule r)
{
    return r.CreatedBy.CompanyID == currentUser.CompanyID;
});

but this doesn't:

return rules.Where(r => r.CreatedBy.CompanyID == currentUser.CompanyID);
  • It's EF Code first and CreatedBy and ModifiedBy are both virtual properties.
  • r.CreatedBy and currentUser are both instances of the same class (if you didn't already work this out)
  • What the second snippet is returning is an empty list. It's as though the eager loading isn't working and the lambda doesn't cause a lazy load.

Note: I've just discovered that if I change the first line to

var rules = context.Rules.Include(r => r.CreatedBy)
    .Include(r => r.ModifiedBy).ToList()

then the lambda works. The question still stands though. Why to I have to use the ToList() or the delegate. I'm doing the same thing elsewhere in the same class and it works as I'd expect.

Thanks

Was it helpful?

Solution

This is because lambdas can be implicitly converted to delegates or to expression trees. In the first case, the delegate is converted to an expression tree because rules is IQueryable<> and overload resolution chooses Queryable.Where. When you use the anonymous function, however, that can't be converted to an expression tree, so overload resolution has to choose Enumerable.Where.

When you make rules into a List<>, that forces overload resolution to choose Enumerable.Where, because List<> does not implement IQueryable<>. You could use AsEnumerable() to achieve the same effect without the overhead of creating the list.

As to why this doesn't work when you're "doing the same thing elsewhere in the same class and it works as I'd expect," we might be able to help if you give an example of code that does work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top