繁体   English   中英

实体框架 linq 到 sql 转换问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM