2011-02-18 56 views
0

我需要CTP5的添加或更新模式。 假设模型: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; } 
} 

如果我添加一个新用户时,coresponding地址表也被填充。 但是,如果用户已经在数据库中,我会得到一个DbUpdateException。在这种情况下,我希望用新数据更新数据库中的数据。我怎样才能做到这一点?在数据库

数据

表地址

AddressID位置

1 JohnPlace

2 MaryPlace

3 JimmyPlace

用户I更新已在地址集合1个AddressId:2,Location = GeorgePlace。 但是对于ID = 2,在Db中已经有位置= 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

@Ryan:所以,你可以在数据库中有地址,该地址没有分配给任何用户?你还可以发布你的更新代码吗? – 2011-02-18 08:21:47

+0

我做了类似Jakub Konecki的建议。但我希望能够做一些像context.Users.Add(newUser); context.SaveChanges() – Ryan 2011-02-18 09:02:33

+0

@Ryan:发布你的代码。我们需要知道您是如何接收/创建要更新的用户和地址对象以及实际更新方法的。 – 2011-02-18 09:03:00

回答

0

如果您想更新现有的用户不插入(不叫Add() ) 首先通过Id加载用户,而不是修改其属性,并在上下文中调用SaveChanges()

var db = new DatabaseContext(); 
var user = db.Users.Find(myUserId); 
user.Name = "New Name"; 
db.SaveChanges(); 
0

您当前的问题是,你准备新的用户对象和填充其地址,但地址不是从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();