LINQ:为什么Expression.Call()会引用Db,而CreateQuery()也会
本文关键字:Db CreateQuery 也会 引用 Expression Call LINQ 为什么 | 更新日期: 2023-09-27 18:04:18
所以我试图优化一个查询,对1000行进行文本搜索,并显示100行。为了做到这一点,我试图理解一些代码从微软的101样例查询(在这里找到)。
下面是我想要理解的代码:
[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 left = 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);
}
所以…我意识到这是深奥的,但为什么Expression.Call()需要DbSet引用它传递给CreateQuery作为<T>
?
我相信你要问的是为什么在Expression.Call
中需要第三个参数(类型数组),因为如果你通过代码完成它,你只需要这样做:
custs.Where(pred);
没有泛型形参的代码之所以可以工作是因为隐式键入,其中编译器自动将其转换为:
custs.Where<Customer>(pred);
转换后,实际的字节码包含具有指定泛型的调用。当你构建Expression
时,你没有所有的细节,比如隐式类型,所以你必须确切地指定调用什么。