gpt4 book ai didi

c# - EF 核心字符串区分大小写不起作用

转载 作者:行者123 更新时间:2023-12-02 18:29:56 39 4
gpt4 key购买 nike

我有一段在 EF Core 2.2 中工作的代码,用于比较字符串大小写,如下所示。

public async Task<bool> DoesItemNumberExists(Guid revisionId, string itemNumber)
{
var doesExist = await _repository.AnyAsync(a => string.Equals(a.ItemNo, itemNumber, StringComparison.Ordinal) && a.SoqHeading_NP.SoqRevisionId == revisionId);

return doesExist;
}

我在 EF Core 5 中运行相同的代码,但应用程序崩溃了。有帮助吗?

下面是我得到的异常

The LINQ expression 'DbSet<SoqItem>()
.Where(s => s.IsDeleted == False)
.Join(
inner: DbSet<SoqHeading>()
.Where(s0 => s0.SoqRevisionId == __ef_filter__RevisionId_0 && s0.IsDeleted == False),
outerKeySelector: s => EF.Property<Nullable<Guid>>(s, "SoqHeadingId"),
innerKeySelector: s0 => EF.Property<Nullable<Guid>>(s0, "Id"),
resultSelector: (o, i) => new TransparentIdentifier<SoqItem, SoqHeading>(
Outer = o,
Inner = i
))
.Any(s => string.Equals(
a: s.Outer.ItemNo,
b: __itemNumber_0,
comparisonType: Ordinal) && s.Inner.SoqRevisionId == __revisionId_1)' could not be translated. Additional information: Translation of the 'string.Equals' overload with a 'StringComparison' parameter is not supported. See https://go.microsoft.com/fwlink/?linkid=2129535 for more information. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

最佳答案

区分大小写和排序规则在文档中、在文档中、在 Collations and Case Sensitivity 中进行了说明。


这不是 EF Core 5 错误。查询总是无法转换为 SQL,但 EF Core 2 通过将所有内容加载到内存中然后在没有索引的情况下匹配客户端上的记录来弥补这一点。第一版 EF Core 中的 LINQ 翻译非常有限,甚至 GROUP BY 也无法翻译。 Entity Framework 会抛出这种情况。不过,为了避免破坏在 EF 6 中完美运行的代码,EF Core 1 和 2 使用了客户端评估:他们将可以翻译的内容转换为 SQL,然后将数据加载到客户端的内存中,并使用LINQ to 对象。

这意味着,如果您想计算 100K 行的 SUM,EF Core 1-2 会将所有 100K 行加载到内存中,然后将值逐一相加。不要介意连接两个表,每个表有 1000 行 - 这是 100 万次比较。

即使在 EF Core 2.1 中,客户端计算也会生成运行时警告,并且可以完全禁用。在 EF Core 3.1 中,客户端计算被完全禁用。

要让您的查询正常工作,不要尝试强制大小写或排序规则。只需使用一个简单的相等即可:

var itemExists=context.Products.Any(a=>a.ItemNumber == itemNumber && 
a.SoqHeading_NP.SoqRevisionId == revisionId);

这将被转换为 WHERE ItemNumber=@itemNumber && SoqHeading_NP.SoqRevisionId = @revisionId。查询将使用覆盖 ItemNumberSoqRevisionId 列的任何索引来尽快生成结果。

用于相等匹配的排序规则是列的排序规则。如果那是区分大小写的,您将获得区分大小写的匹配。如果不是,您将获得区分大小写的匹配。in。索引是使用列的排序规则构建的,因此如果您尝试使用不同的排序规则进行匹配,您将阻止服务器使用任何索引。

如果你想在不同的查询中使用不同的大小写匹配并且仍然使用索引,你需要为每个情况创建不同的索引。你如何做到这一点取决于数据库

  • 在 SQL Server 中,不区分大小写是最常见的选项。要同时使用 区分大小写的搜索,您可以使用二进制(因此区分大小写)排序规则为计算列创建索引,例如:
alter table Table1 add ItemNumberCS as COLLATE ..._BIN;
create index IX_Table1_ItemNumberCS on Table1 (ItemNumberCS);

区分大小写的查询应使用 ItemNumberCS 列。

  • 在 PostgreSQL 中,所有排序规则都区分大小写。不过从 v12 开始,您可以 create a custom collation并在计算索引表达式中使用它。要使用区分大小写的搜索,您可以创建不区分大小写的排序规则和索引,例如:
CREATE COLLATION case_insensitive (
provider = icu,
locale = 'und-u-ks-level2',
deterministic = false
);

CREATE INDEX IX_Table1_ItemNumberCI ON Table1 (title COLLATE "case_insensitive");`

LINQ 查询无需更改。

关于c# - EF 核心字符串区分大小写不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69554781/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com