【问题标题】:Can't Translate Extension Method Into Store Expression无法将扩展方法转换为商店表达式
【发布时间】:2012-01-31 05:48:29
【问题描述】:

我有一个扩展方法如下:

public static bool SatisfiesSomeCondition(this Post post, SomeObj someObj)
{
   return post.SomeObjId == someObj.SomeObjId;
}

我正在尝试这样使用它:

var query = ctx.Posts.Where(p => p.SatisfiesSomeCondition(someObj)).ToList();

但我得到了错误:

LINQ to Entities 无法识别方法 'Boolean SatisfiesSomeCondition(xx.xx.xx.Post, xx.xx.xx.SomeObj)' 方法,并且该方法无法转换为存储表达式。

如果我将查询更改为:

var query = ctx.Posts.Where(p => p.SomeObjId == someObj.SomeObjId).ToList();

与方法相同。

它工作正常,并执行预期的 T-SQL。

为什么我的第一个查询不起作用?是静态方法,不知道怎么创建表达式树? (例如 WHERE 过滤器)。当然我不必先实现查询? (这意味着我不希望通过网络返回的记录,并且我在这里进行分页/排序,所以这不是一个选项)。

当然,我可以选择可行的方法(例如上述方法),但方法 SatisfiesSomeCondition 是跨域使用的现有方法,我想重复使用该功能,而不是复制它。

有什么想法吗?

【问题讨论】:

    标签: c# entity-framework linq-to-entities entity-framework-4.1 extension-methods


    【解决方案1】:

    改成:

    public static IQueryable<Post> SatisfiesSomeCondition(this IQueryable<Post> query, SomeObj someObj)
    {
       int id = someObj.SomeObjId;
       return query.Where(post => post.SomeObjId == id);
    }
    

    并像这样使用它:

    var query = ctx.Posts.SatisfiesSomeCondition(someObj)).ToList();
    

    这样它应该可以工作。您可以在单个查询中组合多个 Where 条件,因此它至少应该为您提供基本的可重用性。

    【讨论】:

    • 但是我不能使用 OR 运算符,可以吗?请参阅我对 SLaks 答案的评论。
    • 不可以使用或操作。扩展方法不会为您提供在单个条件中组合表达式的可扩展性。
    【解决方案2】:

    LINQ to Entities 引擎无法知道您的静态方法的作用。
    LINQ 查询只能从表达式树转换。

    【讨论】:

    • 很公平。你有什么建议?复制功能?有什么方法可以让我使用该方法而不重复它?
    • 不幸的是,我不知道。您可以创建一个返回 Expression&lt;Func&lt;Post, bool&gt;&gt; 的函数,但您无法编写它。
    • 是的,我正试图让该方法返回谓词,但我的原始查询也有一个 OR 语句,这使得它变得困难。例如:Where(x =&gt; x.Something || x.SatisfiesSomeCondition(someObj))。所以我必须将整个Where 条件合并到方法中。将研究谓词构建器。
    • 也无法与 PredicateBuilder 一起使用,同样的问题。接受这个答案。为了记录,我最终欺骗了过滤逻辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2011-04-20
    • 1970-01-01
    • 2010-11-03
    相关资源
    最近更新 更多