[英]Entity Framework linq to sql conversion issue
与 EF6/linq to SQL 斗争以获得理想的结果。 我宁愿不必在数据库中创建视图。
关于为什么 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 需要生成一个谓词,当您的参数值为空时,该谓词能够可预测地工作,这就是为什么您会看到额外的([Extent1].[AccountId] IS NULL) AND (@p__linq__0 IS NULL)
。 通过将您的参数转换为查询中的下划线类型(在本例中为System.Int32
),EF 不会认为需要这样做,因为它“认为”您的参数不能为空。
所有这些都是必需的,因为默认情况下,您的 SQL 服务器连接将启用ANSI_NULLS
选项,这意味着任何与NULL
比较都将是假的,这就是 EF 需要生成此额外逻辑( IS NULL
运算符)的原因,以确保您当您的参数值为空时,可以获得可预测的结果。
你可以试试这个来看看ANSI_NULLS
的效果:
SET ANSI_NULLS ON;
SELECT 1 WHERE NULL = NULL;
SET ANSI_NULLS OFF;
SELECT 1 WHERE NULL = NULL;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.