如何使用 Entity Framework 在 C# 中为 Messaging/Chatting 系统建模

How to model a Messaging/Chatting system in C# with Entity Framework

我有一个简单的问题

我正在开发一个聊天系统服务,但我遇到了一些有趣的事情。

我目前是这样操作的:

第一个 table :

[Messages] :
SenderID(user),
RecipientID(user),
Content(string) 

当然,每次用户向其他用户发送消息时,我都会将其添加到 table。但是我想到如果一个table有一百万行,它会变得一团糟

所以我想到了另一种方式:

第一个 Table :

[Conversation]
ConversationID,
USER1(user),
USER2(user)

第二个table:

[Messages] in which I have 
ConversationID,
Content(string) 

基本上,我想问的是,我应该使用哪种配置?

这两种解决方案都适用于简单的消息传递。这里的真正问题是,在相同的两个用户之间是否应该存在不止一个消息对话上下文。

如果两个用户每次聊天时总是在同一个会话范围内交谈context/history,那么您的第一个解决方案就足够了。将此场景想象成 Skype 聊天。随着时间的推移,这只是一场漫长的谈话。

如果他们开始聊天时对话上下文发生变化(即,他们的聊天记录在两天不同的对话之间从未真正持续存在),则解决方案二更有意义。将这种情况想象成两个用户之间的电子邮件。第二天我可以给同一个人写另一封电子邮件,但这是不同的对话。

对于解决方案二,您还需要将 USER 添加到第二个 table 以跟踪哪个用户在对话中发送了消息:

第一个 Table :

[Conversation]
ConversationID,
USER1(user),
USER2(user)

第二个table:

[Messages]
ConversationID,
Content(string)
USER(user)

总而言之,仅仅因为 table 会有数百万行并不意味着它不是正确的做法。在这种情况下,它只取决于您的应用程序的要求。

这里还有一个思路,Store一个“消息”的概念。无论是电子邮件、文本、短信还是声音文件。这是您存储消息文本和/或其他元数据的地方。将“消息”视为释放对讲机上的停止通话按钮以结束传输的所有内容,以及直到开始和停止的所有内容都存储在“消息”中。由于用户正在回复来自先前一方的通话请求的“消息”,因此该消息可能与其他消息相关联。

如果你想让整个关系变得简单,那么你可以记录发送给用户的“消息”,“收件箱”和用户发送的消息,“发件箱”。这是当今消息传递心态的代名词。

留言

MessageID, 
Subject, 
Content 
...

已收到消息

MessageReceivedID, 
UserID, 
FromUserID, 
MessageID, 
DateReceived, 
DateRead, 

消息已发送

MessageSentID, 
UserID, 
MessageID, 
DateSent, 
DeletedStatusID

下面的方法应该可以解决您的问题。这是聊天和消息传递的良好基础,通过聊天,您可以从客户端轮询最近的消息并在直观的 UI.

上打耳光

留言

Message {
  MessageId,
  FromId, -- Foreign key User.UserId
  ToId, -- Foreign key User.UserId
  Subject, 
  Content,
  Attachment, -- can be null or default to a 0
  DateReceived, -- can be null or default to 1901 or sumin'
  DateRead
  ...
}

用户

User {
  UserId
  UserName
  ...
}

查询

Inbox = Message where ToId = Me.UserId
Sent = Message where FromId = Me.UserId
Conversation = Group by Subject
Attachment = (Simple = Path to attachment file. || Better = DocumentId)

附件

Document {
  int DocumentId,
  int DocTypeId,
  virtual DocumentType DocumentType,
  string FileName,
  int UserId,
  string mimeType,
  float fileSize,
  string storagePath,
  int OrganizationId,
  string fileHash,
  string ipAddress,
  DateTime DateCreated = DateTime.Now;
}

然后你运行进入群聊的问题。您是向组中的每个收件人发送消息,还是创建每个收件人都可以访问的单个消息?

但我们保持简单。