2010-04-27 179 views
0

我建立ASP.NET MVC2應用程序,並使用實體框架的ORM。我有麻煩更新數據庫中的對象。每次嘗試entity.SaveChanges()時,EF都會在表中插入新行,而不管我想要更新,還是插入即可完成。我想(在接下來的例子等)對象的實體連接,但是後來我如何使用實體框架從asp.net MVC2更新數據庫中的模型?

{"An object with a null EntityKey value cannot be attached to an object context."} 

這裏是我的插入和更新的簡單的功能(這不是真正的汽車,但它是簡單的這樣來解釋,雖然我不要認爲這影響答案的話)......

 public static void InsertOrUpdateCar(this Vehicles entity, Cars car) 
    { 
     if (car.Id == 0 || car.Id == null) 
     { 
      entity.Cars.AddObject(car); 
     } 
     else 
     { 
      entity.Attach(car); 
     } 
     entitet.SaveChanges(); 
    } 

我使用AttachTo(「汽車總動員」,汽車),甚至嘗試過,但我得到了同樣的異常。

任何人有這方面的經驗?

回答

1

如果要更新現有的記錄,那麼你應該有你正在爲你的InsertOrUpdate方法的對象實例中的EntityKey。回到你的代碼,看看你是否能找到丟失的地方。我懷疑你是向用戶呈現一個表單更新此對象,然後映射響應場回一個Car對象,但你沒有通過的EntityKey與它(你可能不希望它顯示給用戶)。

你需要做的是包括使用「隱藏」的輸入型形式的關鍵。您可以使用Html幫助程序Html.Hidden(「Key field name」,key field value)來確保將其傳遞給用戶表單,然後返回到Post代碼。

+0

是的,我有強類型的視圖,我有HttpPost方法從該窗體獲取Car對象。 PK在那裏,它是正確的(我已經使用隱藏字段),但EntityKey爲空。我不知道爲什麼它丟失,也不知道在哪裏:S – Eedoh 2010-04-27 11:25:16

+0

忘記更新...這是問題所在。需要使用相同的實體密鑰進行更改並保存在對象上。 – Eedoh 2010-06-09 08:31:34

3

我可以給你一個粗略的指南,但你的代碼上面不給我一堆的工作。

你會想要做這樣的事情:

using(Entities dataModel = new Entities()) 
{ 
    if(car.Id == 0 || car.Id == null) 
    { 
     dataModel.AddToCars(car); /* There should be a generated method similar to 
     this that just takes a car object minus the Primary Key */ 
    } 
    else 
    { 
     var selectedCar = dataModel.Cars.Where(x => x.Id == car.Id).FirstOrDefault(); 

     if(selectedCar != null) 
     { 
      selectedCar.Name == car.Name; 
      // Continue updating your car stuff 
     } 
    } 

    dataModel.SaveChanges(); 
} 
+0

嗯,我之前正在考慮這種方法,但它看起來像一個「解決方法」,我想用一些更好,更傳統的方法。但是,您的答案很有用。謝謝,這裏投票了。 – Eedoh 2010-04-27 11:18:28

+0

我試過這個解決方法,並且在異常消息中再次失敗: 「操作失敗:無法更改關係,因爲一個或多個外鍵屬性是不可空的當對關係進行更改時,相關的外鍵屬性被設置爲空值,如果外鍵不支持空值,則必須定義新的關係,必須爲外鍵屬性指定另一個非空值,或者不相關的對象必須被刪除「。 – Eedoh 2010-04-27 12:02:24

+0

這聽起來像是模式定義的問題,以及EF數據模型生成器如何從模式生成代碼。我會確保你所有的關係都在edmx中定義好,並且當你在dataModel中添加/更新實體時,每個關係都有適當的數據。 這是EF的黑暗面。 – Tejs 2010-04-27 12:05:34

1

另一種辦法,有些人可能會考慮多一點優雅是:

IContext context = ContextFactory.GetContext(); 
EntityRepo repo = new EntityRepo(context); //Entity Repository 
OtherTableEntity y = new OtherTableEntity() //this could be some other derived value you already have 
//that uniquely identifies the record (or foreign key or other value you want to update) 
Int32 id = 1234; //value to update to 
var z = repo.TableToUpdate.List().Where(x => x.FK_ID == y.FK_ID).FirstOrDefault(); 
if (z != null) 
{ 
    z.FK_ID = id; 
    repo.Commit(); 
} 

把休息之前和repo.Commit();後,有你的SQL查詢窗口開放之前和之後repo.Commit()運行選擇假表。

添加條件基本上你想他們是什麼。致電repo.EntityToUpdate.Add(entity)repo.Commit()

相關問題