LINQ to SQL: Reuse lambda expression

后端 未结 2 696
一生所求
一生所求 2021-02-08 12:38

I stumbled over some strange LINQ to SQL behaviour - can anybody shed some light on this?

I want to define a lambda expression and use it in my LINQ statement. The follo

2条回答
  •  我寻月下人不归
    2021-02-08 12:57

    Okay, here's the deal: dataContext.Table1s is of type IQueryable. IQueryable defines Where and Any methods that take a predicate of type Expression>. The Expression<> wrapper is critical, as this is what allows LINQ to SQL to translate your lambda expression to SQL and execute it on the database server.

    However, IQueryable also includes IEnumerable. IEnumerable also defines Where and Any methods, but the IEnumerable version takes a predicate of type Func. Because this is a compiled function and not an expression, it can't be translated to SQL. As a result, this code...

    Func lambda = x => x.Id > 1000;
    var result = dataContext.Table1s.Where(lambda);
    

    ...will pull EVERY record out of Table1s into memory, and then filter the records in memory. It works, but it's really bad news if your table is large.

    Func lambda = x => x.Id > 1000;
    var result = dataContext.Table2s.Where(x => x.Table1s.Any(lambda));
    

    This version has two lambda expressions. The second one, being passed directly into Where, is an Expression that includes a reference to a Func. You can't mix the two, and the error message you're getting is telling you that the call to Any is expecting an Expression but you're passing in a Func.

    var result = dataContext.Table2s.Where(x => x.Table1s.Any(y => y.Id > 1000));
    

    In this version, your inner lambda is automatically being converted to an Expression because that's the only choice if you want your code to be transformed into SQL by LINQ to SQL. In the other cases, you're forcing the lambda to be a Func instead of an Expression - in this case you're not, so it works.

    What's the solution? It's actually pretty simple:

    Expression> lambda = x => x.Id > 1000;
    

提交回复
热议问题