2011-08-16 68 views
12

我有一個用戶表。從其他表中可以看到此表格對像CreatedBy這樣的字段的引用。無法在對象'dbo.User'中插入重複鍵。 r n聲明已終止

問題是,當我插入另一個表的行(例如'x')時,它會嘗試將新用戶插入到用戶表中。

它應該做的是在CreatedBy作爲現有用戶的表'x'中插入一行。

使用Entity Framework 4.任何人都遇到過這樣的問題嗎?

+0

相關問題:http://stackoverflow.com/questions/5449724/entity-framework-code-first-cannot-insert-duplicate-key-in-object-db – Stefan

回答

31

您可以將實體與相關實體一起插入,也可以插入實體而不引用相關實體,只需引用現有實體即可。這取決於你編寫的代碼。

實施例1:

User user = GetUserFromSomewhere(); 
using (var context = new MyContext()) 
{ 
    Order order = new Order(); 
    order.CreatedBy = user; 

    context.Orders.AddObject(order); 
    // will put both order and related entity user into Added state 
    // because user is not attached to the context 

    context.SaveChanges(); 
    // creates new order and new user and sets the relationship between them 
} 

實施例2:

using (var context = new MyContext()) 
{ 
    User user = context.Users.SingleOrDefault(u => u.Id == 1); 
    // query attaches this user to this context 
    // user is in state Unchanged now 

    Order order = new Order(); 
    order.CreatedBy = user; 

    context.Orders.AddObject(order); 
    // will put the order into Added state but doesn't touch the 
    // state of already attached related entities -> user remains 
    // in state Unchanged 

    context.SaveChanges(); 
    // creates new order with reference to user, but doesn't create new user 
} 

實施例3:

User user = GetUserFromSomewhere(); 
using (var context = new MyContext()) 
{ 
    context.Users.Attach(user); 
    // we attach explicitely to the context telling EF thereby 
    // that we know that this user exists in the DB 
    // user is in state Unchanged now 

    Order order = new Order(); 
    order.CreatedBy = user; 

    context.Orders.AddObject(order); 
    // will put the order into Added state but doesn't touch the 
    // state of already attached related entities -> user remains 
    // in state Unchanged 

    context.SaveChanges(); 
    // creates new order with reference to user, but doesn't create new user 
} 

編輯

實施例4:

int userId = GetUserIdFromSomewhere(); 
using (var context = new MyContext()) 
{ 
    var user = new User { Id = userId }; 
    // we create a stub user entity with the correct primary key 
    // It's not necessary to set other properties 
    // to only set the relationship to the order 

    context.Users.Attach(user); 
    // we attach explicitely to the context telling EF thereby 
    // that we know that this user exists in the DB 
    // user is in state Unchanged now 

    Order order = new Order(); 
    order.CreatedBy = user; 

    context.Orders.AddObject(order); 
    // will put the order into Added state but doesn't touch the 
    // state of already attached related entities -> user remains 
    // in state Unchanged 

    context.SaveChanges(); 
    // creates new order with reference to user, but doesn't create new user 
} 
+0

我的問題的優秀演繹。只是我已經在做示例3.唯一的區別是,不是通過GetUserFromSomeWhere()獲取用戶;我通過WCF線傳遞用戶對象作爲參數...所以我失去了上下文。這導致實體框架也插入用戶對象。因爲它不知道已經存在。 我將不得不從客戶端發送ID並根據服務器端的ID獲取用戶。或者我將不得不在模型中包含外鍵列......以便我可以做到這一點... order.CreatedBy.Id = id; –

+2

@Nilotpal:'GetUserFromSomeWhere()'在某種程度上是對WCF服務的模擬,或者通常你的'用戶'實體與你在其中進行修改的上下文分離。使用外鍵屬性通常是一個好主意。或者,您也可以使用「存根」用戶實體並將其附加到上下文中:var user = new User {Id = userId}; context.Users.Attach(用戶);'。對於'Attach',只需要設置主鍵屬性即可。如果您只想設置與訂單的關係,則其他屬性可能保持爲空。請參閱上面的「編輯」部分中的示例4。 – Slauma

+1

@Slauma - +1。優秀的例子。 –

相關問題