免责声明 - 这既是一个理论问题,也是一个实际案例问题。遗产和其他情况使其成为现实。
问题是: 我可以强制 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:内部错误:已达到表达式服务限制。请在查询中查找潜在的复杂表达式,并尝试简化它们。”
当我查看生成的 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?
您是否尝试过批量处理数据?
例如:
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());
}
或者您可以创建临时表来存储数据,然后继续处理实际表。