我需要CTP5的添加或更新模式。 假设模型:
public class User
{
public int UserId { get; set; }
public ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int AddressID { get; set; }
public string Location { get; set; }
}
如果我添加新用户,则还会填充相应的地址表。 但是如果用户已经在DB中,我将得到一个DbUpdateException。在这种情况下,我希望使用新数据更新数据库中的数据。我怎么能这样做?
数据库中的数据
表格地址
地址ID位置
1 JohnPlace
2 MaryPlace
3 JimmyPlace
我更新的用户在Addresses集合1中有AddressId:2,Location = GeorgePlace。 但是对于ID = 2,在Db中已经存在location = MarryPlace的记录。我希望GeorgePlace覆盖MarryPlace。
我不能拥有未分配给用户的地址
我创建了一个像这样的用户:
var user=new User();
user.Id=GetUserIDfromService();
foreach(var address in GetAddressesFromService(user.Id)){
user.Addresses.Add(address);
}
context.Users.Add(user);
context.SaveChanges();//this may throw an exception, because there is already a user with this id.
答案 0 :(得分:0)
如果您想更新现有用户,请不要插入(请勿拨打Add()
)
首先按用户ID加载用户,然后修改其属性,并在上下文中调用SaveChanges()
。
var db = new DatabaseContext();
var user = db.Users.Find(myUserId);
user.Name = "New Name";
db.SaveChanges();
答案 1 :(得分:0)
您当前的问题是您准备新的User对象并填充其地址,但地址不是通过相同的上下文从DB加载的,因此上下文不知道它们。当您调用Add方法时,它将获取对象图中的所有对象并将它们标记为新(要插入)。避免这种情况的唯一方法是手动说出哪个地址是新的,哪个只是在将它们添加到用户实例之前从上下文修改或加载地址。
标记地址的代码如下所示:
var user = new User();
user.Id = GetUserIDfromService();
context.Users.Add(user);
foreach(var address in GetAddressesFromService(user.Id))
{
context.Addresses.Attach(address);
// Let say that new address always have 0 Id
context.Entry(address).State = address.Id == 0 ? EntityState.Added : EntityState.Modified;
user.Addresses.Add(address);
}
context.SaveChanges();