猿问

实体框架 linq 到 sql 的转换问题

使用 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)


慕姐4208626
浏览 78回答 1
1回答

慕田峪4524236

请尝试:.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 时以可预测的方式工作,这就是为什么您将看到额外的 .通过将参数转换为查询中的下划线类型(在本例中),EF 将看不到执行此操作的必要性,因为它“认为”参数不能为 null。([Extent1].[AccountId] IS NULL) AND (@p__linq__0 IS NULL)System.Int32所有这些都是必需的,因为默认情况下,SQL Server 连接将启用该选项,这意味着与 的任何比较都将是 false,这就是 EF 需要生成此额外逻辑(运算符)的原因,以确保在参数值为 null 时可以获得可预测的结果。ANSI_NULLSNULLIS NULL您可以尝试此操作以查看操作中的效果:ANSI_NULLSSET ANSI_NULLS ON;SELECT 1 WHERE NULL = NULL;SET ANSI_NULLS OFF;SELECT 1 WHERE NULL = NULL;
随时随地看视频慕课网APP
我要回答