【问题标题】:Linq expression not supported不支持 Linq 表达式
【发布时间】:2017-01-26 04:44:31
【问题描述】:

我有以下 LINQ to Entities 表达式:

var allItemsOver64 =
  _inventoryContext.Items.Where(
  i => DateTimeHelper.CalculateAgeInYears(i.PrimaryInsured.DoB, now) >= 65);

问题是,当我使用 allItemsOver64 时,它说不支持此表达式。我感觉这个错误是由于调用了CalculateAgeInYears 方法而发生的。为什么会发生这种情况,我该如何解决?

谢谢,

萨钦

编辑:

即使将代码更改为使用 IEnumerables,我仍然会遇到相同的错误。这是我现在的代码:

DateTime now = DateTime.UtcNow;
            var allItemsOver64 =
                _inventoryContext.Items.Where(
                    i => DateTimeHelper.CalculateAgeInYears(i.PrimaryInsured.DoB, now) >= 65).AsEnumerable();
            IEnumerable<Item> items65To69 = allItemsOver64.Where(
                i =>
                DateTimeHelper.CalculateAgeInYears(i.PrimaryInsured.DoB, now) >= 65 &&
                DateTimeHelper.CalculateAgeInYears(i.PrimaryInsured.DoB, now) <= 69).AsEnumerable();

【问题讨论】:

  • 所以它适用于&lt;=65?
  • 我不需要 65 岁以下的任何物品,因此这甚至不属于等式。

标签: c# linq entity-framework-4 linq-to-entities


【解决方案1】:

您不能在 EF 查询中调用 C# 方法,因为 EF 不知道如何将方法转换为 SQL。

相反,首先调用.AsEnumerable() 以强制Where() 在本地运行。

【讨论】:

  • 这会起作用...但是如果该集合包含数百万条记录怎么办?这将需要首先将所有记录检索到客户端。然后为内存中的每个项目调用该函数。它真的会影响性能。
【解决方案2】:

如果我从您的函数名称中正确推断,我认为这可能是您正在寻找的:

using System.Data.Objects.SqlClient;

var allItemsOver64 = _inventoryContext
                     .Items
                     .Where(i => (SqlFunctions
                                  .DateDiff("dd", i.PrimaryInsured.DoB, now) / 365.0) 
                                  >= 65.0);

【讨论】:

  • 您在正确的轨道上,但您将离开一年,直到此人的出生日期超过 今年年。
  • @Sachin 很抱歉没有看到您在代码中使用 SqlFuntions
  • 啊不,我明白了,我实际上没有 SqlFunctions。但正如 Yuck 所说,这行不通。
  • 根据 Yuck 的说法:“在这个人今年的出生日期过去之前,您将休息一年”。
  • 我要试试这个方法。
【解决方案3】:

因为 Linq 无法将您的辅助方法解释为 SQL 命令。您应该在数据库端实现这样的逻辑,或者选择所有值,然后才在客户端进行检查。这两个对我来说都不好看,这就是为什么我总是尝试简化数据库,尽可能地进行简单的查询。

【讨论】:

  • 如何在db端实现这个逻辑?
  • 例如添加函数并在查询中选择它的结果,或者添加视图,它将选择您的助手已经计算的字段之一。有几十种方法,但尽量避免它,它确实使查找错误变得复杂,另一方面,将所有内容选择给客户端会使查询结果变得巨大并损害性能。
  • 嗨,约翰尼,我正在尝试客户端方法,将结果设为 IEnumerable(请参阅上面的编辑),但我仍然遇到完全相同的错误。这是为什么呢?
  • @SachinKainth,您必须先制作 AsEnumerable 或 ToList,以使 ORM 从 db 获取数据,然后在您的函数中应用 where。目前你正在反之亦然。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多