强制 EF6 在 QUERY 表达式中使用 VARCHAR 而不是 NVARCHAR [重复]

问题描述 投票:0回答:1

免责声明 - 这既是一个理论问题,也是一个实际案例问题。遗产和其他情况使其成为现实。

问题是: 我可以强制 EF6 在 QUERY 表达式中使用 VARCHAR 而不是 NVARCHAR 吗?

一个原因可能是性能(我知道这可能不是查看性能的正确位置,请参阅免责声明),在我正在工作的数据库中,我注意到存在显着的性能差异。当我使用 VARCHAR 而不是 NVARCHAR 时。

场景

我的列表中有 40.000 个 ID,我用它们来查询我的客户表。

List<string> ids = new[]{"Id1", "Id2" .. "Id40000"}.ToList();
var customers = dbContext.Customers.Where(c => ids.Contains(c.Id));

SQL表中的Id列是VARCHAR(50) 并且 Customers.Id 是字符串

但这会导致此错误:

“SqlException:内部错误:已达到表达式服务限制。请在查询中查找潜在的复杂表达式,并尝试简化它们。”

https://learn.microsoft.com/en-us/sql/relational-databases/errors-events/mssqlserver-8632-database-engine-error?view=sql-server-ver16

当我查看生成的 SQL 时,我可以看到 EF 已将所有 Id 设置为 NVARCHAR,

WHERE ([Project1].[C10] IN (N'Id1', N'Id2', N'Id3', ..... , N'Id40000')

如果我将它们设置为 VARCHAR 并直接针对数据库运行查询,则没有问题。

WHERE ([Project1].[C10] IN ('Id1', 'Id2', 'Id3', ..... , 'Id40000')

所以我的问题是,如何强制 EF 在表达式中使用 VARCHAR?

c# sql-server entity-framework linq
1个回答
-2
投票

您是否尝试过批量处理数据?

例如:

int batchSize = 1000;
var customers = new List<Customer>();

for (int i = 0; i < ids.Count; i += batchSize)
{
    var batchIds = ids.Skip(i).Take(batchSize).ToList();
    customers.AddRange(dbContext.Customers.Where(c => batchIds.Contains(c.Id)).ToList());
}

或者您可以创建临时表来存储数据,然后继续处理实际表。

© www.soinside.com 2019 - 2024. All rights reserved.