2011-02-18 85 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();