LINQ: Why does Expression.Call() reference the Db when CreateQuery() does as well?
So I'm trying to optimize a query that does a text search on 1000s of rows and displays 100s of them. To do so, I'm trying to understand some code from Microsoft's 101 Sample Queries (found here).
Here is the code I wish to understand:
[Category("Advanced")]
[Title("Dynamic query - Where")]
[Description("This sample builds a query dynamically to filter for Customers in London.")]
public void LinqToSqlAdvanced02()
{
IQueryable<Customer> custs = db.Customers;
ParameterExpression param = Expression.Parameter(typeof(Customer), "c");
Expression right = Expression.Constant("London");
Expression l开发者_StackOverfloweft = Expression.Property(param, typeof(Customer).GetProperty("City"));
Expression filter = Expression.Equal(left, right);
Expression pred = Expression.Lambda(filter, param);
Expression expr = Expression.Call(typeof(Queryable), "Where", new Type[] { typeof(Customer) }, Expression.Constant(custs), pred);
IQueryable<Customer> query = db.Customers.AsQueryable().Provider.CreateQuery<Customer>(expr);
ObjectDumper.Write(query);
}
So...I realize this is esoteric, but why does Expression.Call() need the DbSet reference it's passed to CreateQuery as <T>
?
I believe what you're asking is why the third parameter (array of types) is needed in Expression.Call
because if you did it through code, you'd only have to do this:
custs.Where(pred);
The reason why the code works without the generic parameter is because of implicit typing, where the compiler translates that automatically to:
custs.Where<Customer>(pred);
After it translates it, the actual bytecode contains the call with the generics specified. When you build the Expression
, you don't have all the niceties like implicit typing, so you have to specify exactly what gets called.
精彩评论