2

次の LINQ2SQL クエリがあります。

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

型はすべて文字列です。

私のDBには、クエリによって返される必要がある行があります。

value="0", controlledParamId =null and FacilityId ="abc"このクエリがnullを返すとき、しかし私が次のように書いたとき:

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

テストではありませんでしたnull

私は何を間違っていますか?

PS私も試しc.DriverControlledParameterId.Equals(controlledParamId)ましたが、うまくいきません。

4

1 に答える 1

5

問題は、LINQ2SQL が式に対して特別な処理を行うことc.DriverControlledParameterId == nullです。これは SQL に変換されますDriverControlledParameterId IS NULL
ただし、isの場合でもc.DriverControlledParameterId = controlledParamIdSQL に変換されます。SQL ではundefined であり、そのため never .DriverControlledParameterId = :p1controlledParamIdnullDriverControlledParameterId = NULLTRUE

修正方法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();

その 3 番目のオプションは、私が使用するものです。私の意見では、これはオプション 2 よりも読みやすく、最初のコードのように繰り返されるコードはありません。

于 2013-09-25T13:04:59.803 に答える