我将一些数据保存到我的数据库中,我首先使用代码。一切正常,直到我想要改变一个实体。例如:我向数据库中添加了四个人,当我更新其中一个人时,数据库会添加所有人的重复项。
更新 问题出在这段代码中:
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>();
}
}
一切正常!但是当我连接到我的数据库时,有四个新人。 =(
答案 0 :(得分:0)
不要调用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
方法,只需调用{ {1}}方法。
如果您想了解更多如何使用这些方法,请查看此link。