gpt4 book ai didi

c# - Entity Framework linq 到 sql 的转换问题

转载 作者:行者123 更新时间:2023-11-30 22:56:28 26 4
gpt4 key购买 nike

与 EF6/linq to SQL 战斗以获得期望的结果。我宁愿不必在数据库中创建 View 。

关于为什么 EF 以这种方式转换它或如何以其他方式欺骗它的任何想法?

我的 linq 谓词:

.Where(x => 
(x.AccountId == viewModel.AccountId || x.AccountId == null)
&& (x.CompanyId == viewModel.CompanyId || x.Company == null)
&& (x.FacilityId == viewModel.FacilityId || x.FacilityId == null)
)

生成的SQL:

WHERE 
(([Extent1].[AccountId] = 1)
OR (([Extent1].[AccountId] IS NULL) AND (1 IS NULL))
OR ([Extent1].[AccountId] IS NULL)
)
AND
(
([Extent1].[CompanyId] = 11)
OR (([Extent1].[CompanyId] IS NULL) AND (11 IS NULL))
OR ([Extent2].[Id] IS NULL)
)
AND
(
([Extent1].[FacilityId] = 1)
OR (([Extent1].[FacilityId] IS NULL) AND (1 IS NULL))
OR ([Extent1].[FacilityId] IS NULL)
)
AND
(
([Extent1].[FacilityId] = 1)
OR (([Extent1].[FacilityId] IS NULL) AND (1 IS NULL))
)

我认为我会得到的 SQL 确实达到了预期的结果:

WHERE 
(
([Extent1].[AccountId] = 1)
OR ([Extent1].[AccountId] IS NULL)
)
AND
(
([Extent1].[CompanyId] = 11)
OR ([Extent2].[Id] IS NULL)
)
AND
(
([Extent1].[FacilityId] = 1)
OR ([Extent1].[FacilityId] IS NULL)
)

最佳答案

请尝试:

.Where(x => 
(x.AccountId == (int)viewModel.AccountId || x.AccountId == null)
&& (x.CompanyId == (int)viewModel.CompanyId || x.Company == null)
&& (x.FacilityId == (int)viewModel.FacilityId || x.FacilityId == null)
)

或者:

var accountId = viewModel.AccountId.GetValueOrDefault();
var companyId = viewModel.CompanyId.GetValueOrDefault();
var facilityId = viewModel.FacilityId.GetValueOrDefault();
...
...
.Where(x =>
(x.AccountId == accountId || x.AccountId == null)
&& (x.CompanyId == companyId || x.Company == null)
&& (x.FacilityId == facilityId || x.FacilityId == null)
)

您的原始查询将可空类型引用为参数,因此,EF 需要生成一个谓词,该谓词能够在您的参数值为 null 时以可预测的方式工作,这就是为什么您会看到额外的 ([Extent1] .[AccountId] 为空)和(@p__linq__0 为空)。通过将参数强制转换为查询中的下划线类型(在本例中为 System.Int32),EF 将看不到这样做的必要性,因为它“认为”您的参数不能为 null。

所有这些都是必需的,因为默认情况下,您的 SQL 服务器连接将启用 ANSI_NULLS 选项,这意味着与 NULL 的任何比较都将是错误的,这就是为什么EF 需要生成此额外逻辑(IS NULL 运算符),以确保您在参数值为 null 时可以获得可预测的结果。

您可以试试看 ANSI_NULLS 的实际效果:

SET ANSI_NULLS ON;
SELECT 1 WHERE NULL = NULL;

SET ANSI_NULLS OFF;
SELECT 1 WHERE NULL = NULL;

关于c# - Entity Framework linq 到 sql 的转换问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54472964/

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