我正在实现 Chat functionality非常喜欢 asp.net 中的这个。这是模型解释
我的类(class)是:User、Conversaiton 和 Message:
public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
public string UserName { get; set; }
//keys
public ICollection<Conversation> Conversations { get; set; }
}
public class Conversation
{
public Guid ID { get; set; }
public ICollection<Message> Messages { get; set; }
public User RecipientUser { get; set; }
public Guid SenderUserId { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}
最后,
public class Message
{
public int ID { get; set; }
public string Text { get; set; }
public bool IsDelivered { get; set; }
public bool IsSeen { get; set; }
public Guid SenderUserId { get; set; }
public Conversation Conversation { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}
我正在使用 EntityTypeConfiguration 使用流利的 Api,它们是:
public class UserConfig : EntityTypeConfiguration<User>
{
public UserConfig()
{
HasMany(x => x.Conversations).WithRequired(x => x.RecipientUser).HasForeignKey(x => x.SenderUserId);
}
}
public class ConversationConfig : EntityTypeConfiguration<Conversation>
{
public ConversationConfig()
{
HasKey(x => x.ID);
HasRequired(x => x.RecipientUser).WithMany(x => x.Conversations);
HasMany(x => x.Messages).WithRequired(x => x.Conversation).HasForeignKey(x => x.SenderUserId);
}
}
但是我得到如下错误: 违反了多重约束。关系“DataAcessLayer.Conversation_RecipientUser”的角色“Conversation_RecipientUser_Target”具有多重性 1 或 0..1。
如果有人能帮助我。非常感谢!!!
最佳答案
我在使用您的模型时没有得到异常,但这并不重要,因为无论如何您都必须进行一些更改。
首先,UserConfig
中的这个配置...
HasMany(x => x.Conversations).WithRequired(x => x.RecipientUser)
.HasForeignKey(x => x.SenderUserId);
...对我来说没有意义。这意味着对话属于接收者,而不属于发送者,这本身就有些出乎意料。但是外键的名称是 SenderUserId
。如果您将对象保存到此模型中,SenderUserId
将获得收件人的 ID
的值!
其次,假设前一点是一个错误,你通过定义...使它变得比必要的更难
public User RecipientUser { get; set; }
public Guid SenderUserId { get; set; }
这意味着您只能通过显式连接 SenderUserId
从 Conversation
导航到发件人 User
。反之,只能通过设置RecipientUser
来设置收件人,不能简单地设置一个外键值。
第三,你不应该在 Message
中有这个 SenderUserId
。它应该是 ConversationId
而不是。您可以通过它所属的 Conversation
找到 Message
的发件人。
总而言之,我把你的模型改成这样,将它减少到最低限度,并使用 int
作为 ID
,只是因为它更容易阅读:
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public ICollection<Conversation> Conversations { get; set; }
}
public class Conversation
{
public int ID { get; set; }
public int SenderUserID { get; set; }
public User SenderUser { get; set;}
public int RecipientUserID { get; set; }
public User RecipientUser { get; set; }
public ICollection<Message> Messages { get; set; }
}
public class Message
{
public int ID { get; set; }
public string Text { get; set; }
public int ConversationID { get; set; }
public Conversation Conversation { get; set; }
}
唯一的配置:
public class ConversationConfig : EntityTypeConfiguration<Conversation>
{
public ConversationConfig()
{
HasKey(c => c.ID);
HasRequired(c => c.SenderUser).WithMany(u => u.Conversations)
.HasForeignKey(c => c.SenderUserID).WillCascadeOnDelete(true);
HasRequired(c => c.RecipientUser).WithMany()
.HasForeignKey(c => c.RecipientUserID).WillCascadeOnDelete(false);
HasMany(c => c.Messages).WithRequired(x => x.Conversation)
.HasForeignKey(x => x.ConversationID);
}
}
(其中一个外键没有级联删除,因为这会导致 SQL-Server 错误:多个级联路径)。
一个简单的测试:
using (DbContext db = new DbContext(connectionString))
{
var send = new User { Name = "Sender" };
db.Set<User>().Add(send);
var rec = new User { Name = "Recipient" };
var messages = new[] { new Message { Text = "a" }, new Message { Text = "b" } };
var conv = new Conversation { SenderUser = send, RecipientUser = rec, Messages = messages };
db.Set<User>().Add(rec);
db.Set<Conversation>().Add(conv);
db.SaveChanges();
}
结果:
用户:
ID Name
1 Recipient
2 Sender
转化:
ID RecipientUserID SenderUserID
11 1 2
消息:
ID Text ConversationID
21 a 11
22 b 11
关于c# - 实现聊天功能时出现违反多重约束的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38239013/