LINQ:为什么Expression.Call()在CreateQuery()的同时引用Db?

时间:2011-08-02 01:24:08

标签: c# linq linq-to-sql linq-to-entities

所以我正在尝试优化一个在1000行上进行文本搜索并显示100个行的查询。为此,我试图了解Microsoft的101个样本查询(找到here)中的一些代码。

以下是我希望了解的代码:

    [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引用它作为<T>传递给CreateQuery?

1 个答案:

答案 0 :(得分:3)

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

custs.Where(pred);

代码在没有泛型参数的情况下工作的原因是隐式类型,其中编译器自动将其转换为:

custs.Where<Customer>(pred);

翻译后,实际的字节码包含指定泛型的调用。当您构建Expression时,您没有像隐式类型那样的所有细节,因此您必须准确指定要调用的内容。