Ale*_*kiy 2 c# sql linq linq-to-sql
我有以下LINQ2SQL查询:
var map =
dbContext.TCPDriverMappings.FirstOrDefault(
c => c.DriverFacilityId == tcpDms.FacilityId &&
c.DriverControlledParameterId == controlledParamId &&
c.DriverValue == value);
Run Code Online (Sandbox Code Playgroud)
所有类型都是字符串.
在我的数据库中,我有一行,必须通过查询返回.
当value="0", controlledParamId =null and FacilityId ="abc"此查询返回null时,但是当我写下以下内容时:
var test = dbContext.TCPDriverMappings.FirstOrDefault(
c => c.DriverFacilityId == "abc" &&
c.DriverControlledParameterId == null &&
c.DriverValue == "0");
Run Code Online (Sandbox Code Playgroud)
测试没有 null
我究竟做错了什么?
PS我也试过c.DriverControlledParameterId.Equals(controlledParamId)但它也行不通.
问题是,LINQ2SQL对表达式有一个特殊的处理c.DriverControlledParameterId == null.它被翻译成SQL DriverControlledParameterId IS NULL.
但是c.DriverControlledParameterId = controlledParamId被翻译成SQL DriverControlledParameterId = :p1,即使controlledParamId是null.在SQL中DriverControlledParameterId = NULL是未定义的,因此永远不会TRUE.
如何解决:null具体处理案例:
TCPDriverMapping test;
if(controlledParamId == null)
test = dbContext.TCPDriverMappings.FirstOrDefault(
c => c.DriverFacilityId == "abc" &&
c.DriverControlledParameterId == null &&
c.DriverValue == "0");
else
test = dbContext.TCPDriverMappings.FirstOrDefault(
c => c.DriverFacilityId == "abc" &&
c.DriverControlledParameterId == controlledParamId &&
c.DriverValue == "0");
Run Code Online (Sandbox Code Playgroud)
或者像这样:
var test = dbContext.TCPDriverMappings.FirstOrDefault(
c => c.DriverFacilityId == "abc" &&
((controlledParamId == null &&
c.DriverControlledParameterId == null) ||
c.DriverControlledParameterId == controlledParamId) &&
c.DriverValue == "0");
Run Code Online (Sandbox Code Playgroud)
或者像这样:
IQueryable<TCPDriverMapping> query =
dbContext.TCPDriverMappings.Where(c => c.DriverFacilityId == "abc" &&
c.DriverValue == "0");
if(controlledParamId == null)
query = query.Where(c => c.DriverControlledParameterId == null);
else
query = query.Where(c => c.DriverControlledParameterId == controlledParamId);
var test = query.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
我会使用第三个选项.在我看来,这比选项2更具可读性,并且没有像第一个那样重复的代码.