c# - 实现聊天功能时出现违反多重约束的错误

标签 c# asp.net asp.net-mvc entity-framework ef-code-first

我正在实现 Chat functionality非常喜欢 asp.net 中的这个。这是模型解释 Model is like this

我的类(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; }

这意味着您只能通过显式连接 SenderUserIdConversation 导航到发件人 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/

相关文章:

c# - 从数据表中选择不同的记录

c# - 通过存储库将数据库实体映射到域实体 - 静态属性或单独的服务?

c# - 如何从此方法返回 Dictionary<string,Dictionary<int,decimal>> ?

c# - 如何在visual studio中添加资源文件

asp.net - 由于检索用户的本地ap失败,无法生成SQL Server的用户实例

asp.net-mvc - MVC3 DbContext 保存后获取新模型的 ID?

c# - Linq 在 MVC View 中不起作用

c# - 不等待按任意键继续退出控制台...

c# - 是否可以捕获并处理网站卸载事件 - asp.net 网页 razor 2?

asp.net - 如何通过门户中的注销按钮从所有打开的 Web 应用程序中注销?