实体框架不会将数据库上下文中仍然存在的对象与从不同类引用的同一对象相关联

本文关键字:对象 同类 关联 引用 存在 框架 数据库 上下文 实体 | 更新日期: 2023-09-27 18:24:45

我正在尝试向我的数据库
添加message留言.cs:

public class Message
{
    public int Id { get; set; }
    public int SenderId { get; set; }
    public virtual User Sender { get; set; }
    public virtual Collection<Recipient> Recipients { get; set; }
    public MessageTrigger Trigger { get; set; }
    public string Body { get; set; }
    public DateTime CreatedTs { get; set; }
}

我还有一个名为Recipients
的表收件人.cs:

public class Recipient
{
    public int Id { get; set; }
    public int MessageId { get; set; }
    public int UserId { get; set; }
    public virtual User User { get; set; }
    public DateTime? DeliviredOn { get; set; }
}

如您所见,两个表的外键都设置为用户的
ID用户.cs:

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

现在向数据库添加新消息时

 public void Add(Message message)
 {          
     using (var ctx = new ShowcaseContext())
     {
         foreach (var reci in message.Recipients)
         {
             ctx.Users.Attach(reci.User);
         }
         ctx.Messages.Add(message);
         ctx.SaveChanges();
     }
 }

我必须将所有用户附加到上下文,因为如果没有,EF 会再次将用户添加到数据库中。这很好,而Message没有Sender。现在添加Sender and SenderId属性后对于 Message 类,EF 将user再次添加到用户表中。所以我尝试了这样的事情:

 public void Add(Message message)
 {          
     using (var ctx = new ShowcaseContext())
     {
         foreach (var reci in message.Recipients)
         {
             ctx.Users.Attach(reci.User);
         }
         ctx.Users.Attach(message.Sender);  // Here the error is thrown
         ctx.Messages.Add(message);
         ctx.SaveChanges();
     }
 }

但是随后发生此错误:

附加类型为实体的实体时出错。用户, 因为同一类型的另一个实体已经具有相同的主键值

因此,sender的用户已经在数据库上下文中,但上下文似乎没有将此用户与sender的用户相关联。
因此,sender的用户对象将作为副本添加到数据库中。

有没有人知道这个问题的解决方案?
我只想向数据库添加message,而无需 EF 再次将现有用户添加到用户表中。

实体框架不会将数据库上下文中仍然存在的对象与从不同类引用的同一对象相关联

我已经解决了这个问题:

public void Add(Message message)
{          
    using (var ctx = new ShowcaseContext())
    {
        foreach (var reci in message.Recipients)
        {
            ctx.Users.Attach(reci.User);
        }
        ctx.Messages.Add(message);
        ctx.Entry(message.Sender).State = EntityState.Detached;
        ctx.SaveChanges();
    }
}

将消息添加到上下文后,我将sender用户对象与上下文显式分离。
我想这不是最好的解决方案,而是我能想到的唯一有效的解决方案。