【问题标题】:LINQ expression could not be translated无法翻译 LINQ 表达式
【发布时间】:2020-05-11 14:55:22
【问题描述】:

我有以下数据库查询,我试图检查是否存在带有特定条形码的项目,该条形码链接到特定的邮袋。查询如下:

var exists = await dbcontext.Items
                .Include(t => t.MailBagItems)
                .ThenInclude(mt => mt.MailBag)
                .AnyAsync(t => t.Barcode.Equals(barcode) &&
                t.MailBagItems.FirstOrDefault() != null && 
t.MailBagItems.FirstOrDefault().MailBag.Number.ToLower().Equals(mailbagNumber.ToLower()));

由于某种原因,我收到以下异常:

System.InvalidOperationException:无法使用 LINQ 表达式 翻译。要么以可以翻译的形式重写查询, 或通过插入调用显式切换到客户端评估 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync()。

通过删除部分布尔表达式,我知道问题出在我检查邮袋编号的最后一个布尔条件中。但是,如果我删除对 ToLower() 的调用,我会得到同样的错误。有人可以指出我的表达有什么问题以及如何解决吗?请注意,我使用的是 .NET core 3 和 SQL Server。

【问题讨论】:

  • 如果您使用的是 Sql Server,那么您可能不需要 ToLower 调用,因为字符串的比较不区分大小写,除非您有区分大小写的排序规则。我不知道 EF 是否翻译 ToLower。我也不确定 Equals,但您可能想尝试 == 代替
  • 试试string.Equals(t.MailBagItems.FirstOrDefault().MailBag.Number,mailBagNumber,StringComparison.InvariantCultureIgnoreCase)
  • 不幸的是,我已经尝试了您的所有建议,但错误仍然相同。
  • 你的查询有很多误解,试试这个,让我知道结果来详细描述它:var lowerNumber = mailbagNumber.ToLower(); var exists = await dbcontext.Items .AnyAsync(t => t.Barcode == barcode && t.MailBagItems.First().MailBag.Number.ToLower() == lowerNumber));

标签: c# linq


【解决方案1】:

通过将查询更改为以下内容来管理查询:

var exists = dbcontext.Items
                .AnyAsync(t => t.Barcode.Equals(barcode) &&
                            t.MailBagItems.Any(t => t.MailBag.Number.ToLower().Equals(mailbagNumber.ToLower())));

似乎它以前不喜欢 .FirstOrDefault().MailBag。

【讨论】:

  • 您是否只是通过反复试验来解决这个问题?我遇到了同样的问题,它在 .NET Core v2.2 中有效,但现在我们已经升级到 v3.1,我们似乎需要更新一堆 Linq 表达式。
【解决方案2】:

您的AnyAsync 对于 EF 转换为 SQL 来说太复杂了,如果您仍想使用该查询,则必须先实现实体,如下所示:

var exists = dbcontext.Items
                .Include(t => t.MailBagItems)
                .ThenInclude(mt => mt.MailBag)
                .ToListAsync()
                .AnyAsync(t => t.Barcode.Equals(barcode) &&
                t.MailBagItems.FirstOrDefault() != null && 
t.MailBagItems.FirstOrDefault().MailBag.Number.ToLower().Equals(mailbagNumber.ToLower()));

您还缺少await 关键字,还是有意为之?

【讨论】:

  • 不得不将您的 .ToListAsync().AnyAsync 更改为 .ToListAsync().Result.Any 但它可以正常工作,所以谢谢。当我将它复制到问题中时,我错误地省略了等待
猜你喜欢
  • 2021-12-28
  • 2022-12-03
  • 1970-01-01
  • 2021-11-27
  • 2022-10-20
  • 2020-09-29
  • 2021-07-01
  • 1970-01-01
相关资源
最近更新 更多