【问题标题】:IQueryable extension method which becomes an expression成为表达式的 IQueryable 扩展方法
【发布时间】:2014-06-09 11:53:44
【问题描述】:

我正在为现有工具编写IQueryable 实现。此工具的一个非常常见的功能是类似于 Exists at the database 的查询。为了支持这一点,我想用如下方法扩展IQueryable

public static IQueryable<T> WhereExists<T, U>(
    this IQueryable<T> Current,
    IQueryable<U> Other,
    Func<T, Field> CurrentSelector) where U : Entity
    {
        return WhereExists(Current, Other, x => x.ID, CurrentSelector);
    }

public static IQueryable<T> WhereExists<T, U>(
    this IQueryable<T> Current,
    IQueryable<U> Other,
    Func<U, Field> RemoteSelector, 
    Func<T, Field> CurrentSelector) where  U : Entity
    {
        throw new NotImplementedException(
            "This method is only implemented for db-backed queries.");
    }

扩展方法的存在让我可以绕过编译器,真正的功能将在表达式访问者中。

问题是我希望它出现在表达式中,但它会一直运行到扩展方法。是否有必须遵循的限制才能将其放入表达式中(例如使用 .Where 等)?

【问题讨论】:

    标签: c# expression iqueryable


    【解决方案1】:

    让我们看看 .NET 框架是如何做到的:

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

    他们将参数打包成一个调用表达式。

    我建议您尽可能坚持使用默认的Queryable 方法,这样您就不必做太多这个技巧了。

    【讨论】:

    • 感谢您的建议,但我对在这方面做出自己的决定感到很自在。否则很好回答。
    • 当然。这是否回答你的问题?在我看来,确实如此。你的评论让我感到疑惑。
    • 我不能再接受 5 分钟的答案。是的,谢谢。我应该考虑看看实现。我假设编译器有某种构建来支持将这些转换为表达式,并且没有意识到它就像分派给提供者一样简单。再次感谢。
    • 我自己实现了一个 LINQ 提供程序,我也遇到了同样的问题。请注意,有时您的扩展程序不会被调用:items.Where(x =&gt; x.SomeCollection.Any(LAMBDA))。在这里,Any 内部发生的任何事情都不会被调用,因为它被打包为一个表达式。所以你不能依赖电话。因此,您的实际实现应该产生与编译器相同的表达式。这是 LINQ 中的设计问题。
    • 谢谢,这很有帮助——我想知道这个。我以前做过一些,但这个更全面一些。我想打包支持这个 WhereExists,以提高现有开发人员的采用水平,他们熟悉使用该技术编写查询。
    猜你喜欢
    • 1970-01-01
    • 2015-05-04
    • 2020-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    相关资源
    最近更新 更多