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> ?

LINQ:为什么Expression.Call()会引用Db,而CreateQuery()也会

我相信你要问的是为什么在Expression.Call中需要第三个参数(类型数组),因为如果你通过代码完成它,你只需要这样做:

custs.Where(pred);

没有泛型形参的代码之所以可以工作是因为隐式键入,其中编译器自动将其转换为:

custs.Where<Customer>(pred);

转换后,实际的字节码包含具有指定泛型的调用。当你构建Expression时,你没有所有的细节,比如隐式类型,所以你必须确切地指定调用什么。