当匹配存在时,为什么此LINQ查询返回null?

时间:2013-06-04 08:10:11

标签: sql linq

我在服务器端的rest API中有以下LINQ查询,但它与现有记录不匹配:

var existing = (from p in context.GameAction
                where p.GameId == gameId 
                    && p.GameDate == gameDate
                    && p.GamePlayerId == playerId
                    && p.ActionTypeId == actionTypeId
                    && p.PrevBoardPosition == prevBoardposition
                    && (p.ActionTargetId == null || p.ActionTargetId == actionTargetId)
                select p).FirstOrDefault();
if (existing == null)
{
    // create new action record...
}
else
{
    // Update existing game action record...
}

在这种情况下,传递的值为:

int gameId = 34
DateTime gameDate = {03/05/2013 00:00:00}
int actionTypeId = 1
int? prevBoardposition = null
int? actionTargetId = 52

并且存在这些值的记录(但查询返回null):

GameActionId    ActionTypeId    GameId  GameDate    GamePlayerId    ActionTargetId  PrevBoardPosition   MoveCount
2125            1               34      2013-05-03  220             NULL            NULL                13

生成的等效SQL应该是这样的(这确实正确地返回上面的记录):

SELECT [GameActionId]
      ,[ActionTypeId]
      ,[GameId]
      ,[GameDate]
      ,[GamePlayerId]
      ,[ActionTargetId]
      ,[PrevBoardPosition]
      ,[MoveCount]
  FROM [dbo].[GameAction]
  where [GameId]=34 and [GamePlayerId] = 220 
        and [GameDate] = '20130503' 
        and [ActionTypeId]=1 
        and ([PrevBoardPosition] is null or [ActionTargetId]=52)

这是null匹配可为空的int的问题还是我忽略的其他东西?

更新

发送到服务器的生成的SQL查询是:

SELECT 
[Extent1].[GameActionId] AS [GameActionId], 
[Extent1].[ActionTypeId] AS [ActionTypeId], 
[Extent1].[GameId] AS [GameId], 
[Extent1].[GameDate] AS [GameDate], 
[Extent1].[GamePlayerId] AS [GamePlayerId], 
[Extent1].[ActionTargetId] AS [ActionTargetId], 
[Extent1].[PrevBoardPosition] AS [PrevBoardPosition], 
[Extent1].[MoveCount] AS [MoveCount]
FROM [dbo].[GameAction] AS [Extent1]
WHERE ([Extent1].[GameId] = @p__linq__0) AND ([Extent1].[GameDate] = @p__linq__1) AND ([Extent1].[GamePlayerId] = @p__linq__2) AND ([Extent1].[ActionTypeId] = @p__linq__3) AND ([Extent1].[PrevBoardPosition] = @p__linq__4) AND ([Extent1].[ActionTargetId] = @p__linq__5 OR [Extent1].[ActionTargetId] IS NULL)

1 个答案:

答案 0 :(得分:3)

问题在于PrevBoardPosition上的空检查。生成的SQL使用的是PrevBoardPosition = NULL,它永远不会成立。它必须是PrevBoardPosition IS NULL

将其更改为以下内容:

 && prevBoardposition == null ? (p.PrevBoardPosition == null) : (p.PrevBoardPosition == prevBoardposition)

如果EF不支持该条件运算符,则可以将查询更改为仅包含正确的条件:

var query = from p in context.GameAction
            where p.GameId == gameId 
                && p.GameDate == gameDate
                && p.GamePlayerId == playerId
                && p.ActionTypeId == actionTypeId
                && (p.ActionTargetId == null || p.ActionTargetId == actionTargetId)
            select p;

if(prevBoardposition == null)
    query = query.Where(x => x.PrevBoardPosition == null);
else
    query = query.Where(x => x.PrevBoardPosition == prevBoardposition);

var existing = query.FirstOrDefault();