.NET LINQ IQueryable : what is `Expression` for?

标签 .net linq iqueryable

我正在开发 LINQ 提供程序,因此正在实现 IQueryable。

此接口(interface)中 Expression 属性的用途是什么?我通常只是从我的实现中返回类似 Expression.Constant(this) 的东西,但不知道这是否不好。

奇怪的是documentation声明“这允许框架区分 LINQ 和 Entity SQL 查询”。

最佳答案

IQueryable.Expression成员(member)被反馈到IQueryProvider通过各种Queryable.* “运算符(operator)”( .Where() , .Select() , .Join() , ...),例如:

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) {
    if (source == null)
        throw Error.ArgumentNull("source");
    if (predicate == null)
        throw Error.ArgumentNull("predicate");
    return source.Provider.CreateQuery<TSource>( 
        Expression.Call(
            null,
            ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), 
            new Expression[] { source.Expression, Expression.Quote(predicate) }
            ));
}

(取自referencesource)

通常应该是整个表达式。

很明显,如果你直接传递对你的 IQueryable 的完整引用,没有人会杀了你。通过Expression.Constant()上课,但我确实认为这不是“犹太洁食”。

将“真实”表达式放在 Expression 中的意义(就像它是由 Enumerable.AsQueryable() 、EF 和 LINQ-to-SQL 完成的,仅举出三个 IQueryable 提供商)是其他外部类可以自由分析和操作 Expression并以与 Queryable.Where 相同的方式将其反馈给提供者这样做,这样做

Expression expression = source.Expression;
// here "expression" is manipulated
return source.Provider.CreateQuery<SomeType>(expression);

举个例子...有一些“查询修复器”修改查询,如https://github.com/davidfowl/QueryInterceptor (查询的通用修饰符),或 https://github.com/hazzik/DelegateDecompiler , 允许这样做:

var employees = (from employee in db.Employees
                 where employee.FullName == "Test User"
                 select employee).Decompile().ToList();

哪里FullName 映射到数据库中,并且是如下属性:

class Employee
{
    [Computed]
    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }

(FirstNameLastName 映射到数据库)。 DelegateDecompiler 接受 Expression来自 IQueryable , 搜索具有 Computed 的属性属性,反编译它们并将反编译代码(转换为表达式树)放回 IQueryable.Expression (尽管使用 IQueryable.Provider.CreateQuery() )

如果你想保存额外的数据,你可以把它放在Provider中:您可以生成 IQueryProvider 的新实例CreateQuery 中的类方法。这也由 Queryable.* 反馈运算符(因为 CreateQuery<>source.Provider 的实例方法)

关于.NET LINQ IQueryable : what is `Expression` for?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30351396/

相关文章:

c# - .NET 3.5 : anonymous delegate for handlers with ref params

c# - Visual Studio 中的构造函数依赖代码片段

c# - 对于这种简单的 Linq 用法,我的代码效率很低

c# - C#中的数组如何部分实现IList<T>?

sql - 使用 Entity Framework 4.1 的多表连接,我应该使用 lambda 还是 LINQ?

c# - 实现具有某些限制的 JOIN 的算法

c# - 将 IOrderedEnumerable<KeyValuePair<string, int>> 转换为 Dictionary<string, int>

c# - IEnumerable 项目消失 - 存在于 DAL 但不存在于调用者中

c# - Linq 通过 List<T> (System.Collection.Generic.List) 对象过滤 IQueryable<T> (System.Data.Linq.DataQuery) 对象?

c# - IQueryable<a> 到 ObservableCollection<a> 其中 a = 匿名类型