【发布时间】:2020-07-29 20:38:37
【问题描述】:
这里的查询没有按预期工作:
var source = from conv in AuthRepository.Database.Conversations
from msg in AuthRepository.Database.ConversationMessages
let pId = playerId
let lastReadDate =
(
from rd in AuthRepository.Database.ConversationReadDates
where rd.player_id == pId && rd.conversation_id == conv.id
select rd.last_read_date
).FirstOrDefault()
// retrieve last message
where msg.id ==
(
from msgs in AuthRepository.Database.ConversationMessages
where msgs.conversation_id == conv.id
orderby msgs.created descending
select msgs.id
).FirstOrDefault()
// check if last message was read by player
where msg.created > lastReadDate
select conv.id;
return await source.CountAsync();
在我的测试中,“lastReadDate”应该是 DateTime 的默认值,因为没有找到 last_read_date。
但是这个 where 子句失败了:where msg.created > lastReadDate
我已经检查过 msg.created 的值是否正确。
但是当我通过首先检索 lastReadDate 部分然后在第二个查询中使用它来将查询分成两部分时,它可以按预期工作,如下所示:
var sourceReaddate = from rd in AuthRepository.Database.ConversationReadDates
from conv in AuthRepository.Database.Conversations
where rd.player_id == playerId && rd.conversation_id == conv.id
select rd.last_read_date;
var readDate = await sourceReaddate.FirstOrDefaultAsync();
var source = from conv in AuthRepository.Database.Conversations
from msg in AuthRepository.Database.ConversationMessages
let pId = playerId
let lastReadDate = readDate
// check if player is authorized to see the conversation
where !pId.HasValue ||
(
from auth in AuthRepository.Database.ConversationAuthorization
let conversation = auth.conversation
where conversation.id == conv.id && auth.player_id == pId.Value
select conversation.id
).Any()
// retrieve last message
where msg.id ==
(
from msgs in AuthRepository.Database.ConversationMessages
where msgs.conversation_id == conv.id
orderby msgs.created descending
select msgs.id
).FirstOrDefault()
// check if last message was read by player
where msg.created > lastReadDate
where !conv.deleted
select conv.id;
return await source.CountAsync();
我怀疑这是 EF Core 中的一个错误(我使用的是 3.1.6 版本)可能与 issue 相关? 但也许这是我这边的一个错误。你知道问题出在哪里吗?
这个查询还有一个非常令人不安的结果:
var source = from conv in AuthRepository.Database.Conversations
from msg in AuthRepository.Database.ConversationMessages
let pId = playerId
let lastReadDate =
(
from rd in AuthRepository.Database.ConversationReadDates
where rd.player_id == pId && rd.conversation_id == conv.id
select rd.last_read_date
).FirstOrDefault()
// retrieve last message
where msg.id ==
(
from msgs in AuthRepository.Database.ConversationMessages
where msgs.conversation_id == conv.id
orderby msgs.created descending
select msgs.id
).FirstOrDefault()
select new
{
msgCreated = msg.created,
lastReadDate,
read = msg.created <= lastReadDate,
unread = msg.created > lastReadDate,
sup = msg.created > default(DateTime),
defEqual = lastReadDate.Equals(default(DateTime)),
defSup = lastReadDate > default(DateTime),
defInf = lastReadDate < default(DateTime),
};
var result = await source.ToListAsync();
这里是上面查询的结果:
{
msgCreated = {07/29/2020 10:48:14},
lastReadDate = {01/01/0001 00:00:00},
read = false,
unread = false,
sup = true,
defEqual = false,
defSup = false,
defInf = false
}
“已读”和“未读”都被评估为假是不正常的。知道为什么吗?
【问题讨论】:
-
首先,对照 Linq 查询检查生成的 SQL。 EF Core 在
information级别记录查询。
标签: asp.net-core linq-to-sql entity-framework-core