为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
慕姐4208626 2022-08-20 16:55:52
使用 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)) 
查看完整描述

1 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

请尝试:


.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_NULLS


SET ANSI_NULLS ON;

SELECT 1 WHERE NULL = NULL;


SET ANSI_NULLS OFF;

SELECT 1 WHERE NULL = NULL;


查看完整回答
反对 回复 2022-08-20
  • 1 回答
  • 0 关注
  • 77 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信