【问题标题】:LinqKit versus 'Method cannot be translated into a store expression' exceptionLinqKit 与“方法无法转换为存储表达式”异常
【发布时间】:2013-05-01 23:45:46
【问题描述】:

我正在使用 LinqKit,我想编写一个谓词,其中代码必须调用一个普通的布尔方法,如下所示:

var predicate = PredicateBuilder.False<MyEntity>();

var predicate = predicate.And(myEntity => this.EntityMatches(myEntity));

this.ObjectSet.AsExpandable().Where(predicate).ToList();

这是 EntityMatches 方法的(部分):

private bool EntityMatches(MyEntity myEntity)
{
    bool isMatch;

    // I make a call to another library boolean method here.
    isMatch = otherLib.IsEntityMatch(myEntity);

    // I perform some other checks right after.
    isMatch &= // some other conditions ...

    return isMatch;
}

运行延迟执行时出现此异常:

LINQ to Entities 无法识别方法 'Boolean EntityMatches(MyEntity)' 方法,并且这个方法不能翻译 到商店表达式中。

如何重写 EntityMatches 方法以便商店提供者可以理解?

【问题讨论】:

  • linqkit 无关的问题。您的函数适用于 IEnumerable 列表,但不适用于 IQueryable,因为 Linq 无法转换自定义方法
  • 您在哪里看到 IEnumerable 或 IQueryable 类型?谓词变量的类型为Expression&lt;Func&lt;MyEntity, bool&gt;&gt;

标签: c# linq-to-entities linq-expressions linqkit


【解决方案1】:

LinqKit 不是魔术,它看不到 EntityMatches()otherLib.IsEntityMatch() 内部,所以它无法帮助您将它们翻译成 SQL。

LinqKit 可以做的是用简单的部分创建一个复杂的条件。但是每个简单的部分都必须自己翻译成 SQl,我看不出在你的情况下如何做到这一点,特别是因为你正在使用一些外部库。

【讨论】:

  • 所以,我想完成它的唯一方法是尽可能多地从数据库中过滤,然后使用这些自定义方法过滤内存中的结果?
  • @JoanLeaven 是的,可能。但是如果您知道自定义方法的作用,也许您可​​以创建一个执行相同操作的表达式,这意味着您可以完全使用数据库来完成。
  • libary 方法过于复杂,无法重写为 linq 表达式。我最终直接从数据库中过滤了尽可能多的内容,并使用 libary 方法过滤了内存中的结果。
【解决方案2】:

您应该将您的方法转换为 Linq 表达式。 请阅读本文也许会有所帮助 IQueryable extension method for linq2entities

【讨论】:

  • 好建议,但库方法庞大且非常复杂。将其重写为 linq 表达式将需要做很多工作。我最终使用库方法作为内存对象的过滤器。
猜你喜欢
  • 2011-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多