如果使用null检查,LINQ2SQL不返回行

时间:2013-09-25 12:57:10

标签: c# sql linq linq-to-sql

我遵循LINQ2SQL查询:

var map =
                dbContext.TCPDriverMappings.FirstOrDefault(
                      c => c.DriverFacilityId == tcpDms.FacilityId &&
                                 c.DriverControlledParameterId == controlledParamId &&
                                 c.DriverValue == value);

所有类型都是字符串。

在我的数据库中,我有一行,必须通过查询返回。

value="0", controlledParamId =null and FacilityId ="abc"此查询返回null时,但是当我写下以下内容时:

var test = dbContext.TCPDriverMappings.FirstOrDefault(
                          c => c.DriverFacilityId == "abc" &&
                                     c.DriverControlledParameterId == null &&
                                     c.DriverValue == "0");

测试不是null

我做错了什么?

P.S。我也试过了c.DriverControlledParameterId.Equals(controlledParamId)但它也行不通。

1 个答案:

答案 0 :(得分:5)

问题是,LINQ2SQL对表达式c.DriverControlledParameterId == null进行了特殊处理。它被翻译为SQL DriverControlledParameterId IS NULL 但即使c.DriverControlledParameterId = controlledParamIdDriverControlledParameterId = :p1controlledParamId也会转换为SQL 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");

或者像这样:

var test = dbContext.TCPDriverMappings.FirstOrDefault(
               c => c.DriverFacilityId == "abc" &&
                    ((controlledParamId == null &&
                      c.DriverControlledParameterId == null) || 
                     c.DriverControlledParameterId == controlledParamId) &&
                    c.DriverValue == "0");

或者像这样:

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();

我会使用第三种选择。在我看来,这比选项2更具可读性,并且没有像第一个那样重复的代码。