为啥在更新现有实体时会出现重复的实体?
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 在对现有查询添加查询时附加所有实体 [重复]