【发布时间】:2011-09-26 08:17:28
【问题描述】:
我正在努力实现此处所解释的内容: Creating a threaded private messaging system like facebook and gmail, 但是我不完全理解乔尔布朗的回答。谁能解释一下。
这是我的数据库表与示例数据的样子(我假设我出于演示目的正确填写了它):
我需要显示基于 LoginId 的线程列表(最新的在顶部)查询在 LINQ 中会是什么样子? (我要问的是在一组消息线程中,给我每个线程中的 1 条最新消息) - 就像在 facebook 上完成的那样。
-
我需要在消息线程 (LINQ) 中显示所有消息 -> 就像在 facebook 上完成一样,您在其中单击消息时会看到整个“对话”。
请帮忙! 谢谢
编辑 -> 继续 乔尔,这样对吗?
Joel,我有点困惑,你能解释一下吗(cmets/questions 以粗体显示):
这里的想法是,每次用户启动一个全新的线程/消息时,它都会从 THREAD 表中的一条新记录开始。然后将用户添加为 THREAD_PARTICIPANT,并将消息的内容添加到指向包含 THREAD 的 MESSAGE。从 MESSAGE 到 USER 的 FK 表示消息的作者。
LoginId 1 向 LoginId2 发送消息 => 将新记录插入到 MessageThread 表中。还将一条记录插入到 MessageThreadParticipant 记录中,MessageThreadId = 1,LoginId = 1(发送者)。并在 Message 表中插入一条新记录,MessageId =1,MessageThreadid =1,SenderLoginId = 1(正确??)
这是我在那次迭代之后所拥有的:
我想我很困惑,因为 Loginid 2 无法知道有消息给他。 ??或者也许我需要在 MessageThreadParticipant 中插入 2 条记录? (发送者和接收者)-> 这样都可以看到整个“对话”??
EDIT2: 乔,我想我可以这样做:
SELECT
Message.MessageId, Message.CreateDate, Message.Body, Login.Username, Message.SenderLoginId
, (SELECT MessageReadState.ReadDate
FROM MessageReadState
WHERE MessageReadState.MessageId = Message.MessageId
) as ReadDate
FROM Message
INNER JOIN Login ON Message.SenderLoginId = Login.LoginId
INNER JOIN MessageThreadParticipant mtp on mtp.MessageThreadId = Message.MessageThreadId
AND ( Message.MessageId in
( SELECT Max(Message.MessageId)
FROM MessageThreadParticipant INNER JOIN Message
ON MessageThreadParticipant.MessageThreadId = Message.MessageThreadId
GROUP BY MessageThreadParticipant.MessageThreadId
)
)
Where mtp.LoginId = 2
ORDER BY Message.CreateDate DESC;
如果我错了,请纠正我:)
【问题讨论】:
-
Shane,我想你明白了。查看我为扩展示例数据编辑的答案。
-
Shane,我认为您无法使用编辑 2 中的查询来使其正常工作。我看到了两个问题。一是您只会看到相关用户阅读的消息,因为您是在内部加入 MTP。另一个是你试图在你的 FROM (...Message.MessageId in ( SELECT Max(Message.MessageId) ...) 中进行子选择,如果它完全有效的话,这是非常非常规的,我不这样做'认为它不会,因为您不能加入多值相等。子选择属于 WHERE 子句。
标签: asp.net database linq entity-framework database-design