与 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)
)
您的原始查询引用可为 null 的类型作为参数,因此,EF 需要生成一个谓词,该谓词在参数值为 null 时能够按预期工作,这就是为什么您会看到额外的 ([Extent1] .[AccountId] IS NULL) AND (@p__linq__0 IS NULL)
。通过将参数转换为查询中的下划线类型(在本例中为 System.Int32
),EF 将不会认为需要执行此操作,因为它“认为”您的参数不能为 null。
所有这些都是必需的,因为默认情况下您的 SQL 服务器连接将启用 ANSI_NULLS
选项,这意味着与 NULL
的任何比较都将是 false,这就是为什么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/