为啥在更新现有实体时会出现重复的实体?

Posted

技术标签:

【中文标题】为啥在更新现有实体时会出现重复的实体?【英文标题】:Why am I getting duplicate of entities when I updating an existing entity?为什么在更新现有实体时会出现重复的实体? 【发布时间】:2015-01-24 23:28:03 【问题描述】:

我将一些数据保存到我的数据库中,我首先使用代码。一切正常,直到我想改变一个实体。例如:我将四个人添加到数据库中,当我更新其中一个人时,数据库会添加所有人的副本。

更新 问题出在这段代码中:

Conversation newConv = new Conversation  Name = chatPerson.Name ;
        newConv.Members.Add(person);
        newConv.Members.Add(chatPerson);

Conversation 有一个 Members 列表,当我尝试将 Members 添加到列表中时,我会在数据库中获取我的副本。

旧帖

我做的第一件事是加载一个人:

var person = repo.GetWholePerson(3);

返回人的代码:

public Person GetWholePerson(int id)
    
        return _ctx.Persons
            .Include(a => a.Colleagues)
            .Include(a => a.Conversations)
            .FirstOrDefault(p => p.Id == id);
    

这是保存到数据库的代码:

using (Repository<Person> repo = new Repository<Person>())
    
       var per = repo.Get(person.Id);
       var chatPer = repo.Get(chatPerson.Id);

       per.Conversations.Add(newConv);
       chatPer.Conversations.Add(newConv);

       repo.Update(per);
       repo.Update(chatPer);
    

这是存储库中的代码:

public void Update(T entity)
    
        dbSet.Attach(entity);
        _ctx.Entry(entity).State = EntityState.Modified;
        _ctx.SaveChanges();
    

人物类:

public class Person

    public int Id  get; set; 
    public string Name  get; set; 
    public byte[] Image  get; set; 

    public virtual ICollection<Conversation> Conversations  get; set; 

    public virtual ICollection<Person> Colleagues  get; set; 
    public virtual ICollection<Person> Test  get; set; 


    public Person()
    
        Conversations = new List<Conversation>();
        Colleagues = new List<Person>();
        Test = new List<Person>();
    

会话类:

public class Conversation

    public int Id  get; set; 
    public string Name  get; set; 

    public virtual ICollection<Message> Messages  get; set; 
    public virtual ICollection<Person> Members  get; set; 

    public Conversation()
    
        Messages = new List<Message>();
        Members = new List<Person>();
    

一切正常!但是当我连接到我的数据库时,有四个新人。 =(

【问题讨论】:

【参考方案1】:

不要调用Attach 方法,它会将实体标记为Unchanged 状态,这意味着它自从附加到上下文后就没有改变。假定您附加的对象存在于数据库中。 Attach() 对于在这样的场景中更新实体非常有用:

using (var context = new MyDbContext())

   context.Attach(person);
   person.Name = "Bob";
   context.SaveChanges();

如果您知道数据库中已经存在一个实体,并且想要保存之前所做的所有更改,只需调用Entry 方法修改实体状态:

public void Update(T entity)

    _ctx.Entry(entity).State = EntityState.Modified;
    _ctx.SaveChanges();

当你将状态更改为Modified时,实体的所有属性都将被标记为已修改,并在调用SaveChanges时将所有属性值发送到数据库。

其实如果你使用repo的同一个实例来获取和修改你的实体,我想你甚至不需要调用Entry方法,只需调用SaveChanges方法即可。

如果您想了解更多这些方法的工作原理,请查看link。

【讨论】:

感谢您的帖子,我已经更新了我的帖子。如果你能看一看,我会很高兴的。

以上是关于为啥在更新现有实体时会出现重复的实体?的主要内容,如果未能解决你的问题,请参考以下文章

EF Core 在对现有查询添加查询时附加所有实体 [重复]

保存到 DB、C# 时会丢失十进制精度。我正在使用实体框架 [重复]

在实体框架中更新实体的最佳方法[重复]

为啥更改实体的属性时会删除我的 CoreData 信息?

更新大量 NDB 实体失败

Hibernate Criteria 查询 出现重复实体