我在服务器端的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)
答案 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();