【问题标题】:LINQ query working fine in Dot Net Core 2.2 but in 3.1LINQ 查询在 Dot Net Core 2.2 但在 3.1 中工作正常
【发布时间】:2020-08-20 02:29:56
【问题描述】:

Dot Net Core 2.2 中,LINQ 查询按预期工作,但是当我升级到3.1 时,它会引发运行时执行。

[HttpGet("{SINo}")]
public async Task<IEnumerable<dynamic>> SaleHistory(string SINo)
{
    return await (from s in _context.Sales
                  where s.saleInvNo.Contains("|")
                        ? s.saleInvNo.Split("|", StringSplitOptions.None)[1] == SINo
                        : s.saleInvNo == SINo
                  select new
                  {
                      s.saleDate,
                      s.saleInvNo
                  }).ToListAsync();
}

无法翻译。要么重写查询的形式,可以 被翻译,或通过插入显式切换到客户评估 调用 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync()

如何更改此可翻译查询?

注意:Sales 表有大约 100 万条记录。从中,我只想得到一个记录。

【问题讨论】:

  • 虽然它在 EF Core 2.2 中工作,但它会向您发出警告,告诉您此查询将在客户端而不是在您的数据库中进行评估。
  • 另外查看此查询,我强烈建议您规范化此数据以将“SINNo”值拆分到自己的列中 - 没有很好的方法来查询这种类型的数据。
  • 假设saleInvNo 有两个部分基于| 那么如果你尝试s.saleInvNo.Substring(s.saleInvNo.IndexOf("|") + 1) == SINo 而不是s.saleInvNo.Split("|", StringSplitOptions.None)[1] == SINo 怎么样?
  • @SelimYıldız 有时它可能只有 1 个部分。
  • 没关系,它也应该适用,因为您已经检查过s.saleInvNo.Contains("|")。你试过我的建议了吗?

标签: linq asp.net-core-3.1 entity-framework-core-3.1


【解决方案1】:

string.Split 在 LINQ to Entities 中不受支持。所以你需要同时使用SubstringIndexOf,如下所示。

用途:

s.saleInvNo.Substring(s.saleInvNo.IndexOf("|") + 1) == SINo

代替:

s.saleInvNo.Split("|", StringSplitOptions.None)[1] == SINo

见:Split in nested from in Entity Framework

顺便说一下,你应该考虑@DavidG的建议:

另外看这个查询,我强烈建议你规范化这个数据 将“SINNo”值拆分到自己的列中 - 没有很好的 查询此类数据的方法

【讨论】:

  • 虽然这可行,但仍然存在问题。这将生成一个不是“SARGable”的查询。这意味着数据库将使用索引扫描甚至表扫描。解决此问题并拥有高性能数据库的唯一方法是拥有一个包含您要搜索的值的列。
  • @DavidG 你是对的,同意。正如您在评论部分提到的,如果normalise this data to split out the "SINNo" value into its own column 会更好。我已经通过添加您的建议更新了我的答案。感谢您的贡献。
猜你喜欢
  • 2021-11-02
  • 2020-09-27
  • 1970-01-01
  • 2020-01-25
  • 1970-01-01
  • 1970-01-01
  • 2022-10-02
  • 2021-05-25
  • 1970-01-01
相关资源
最近更新 更多