2010-11-17 81 views
3

我有一個包含很多屬性的對象。一堆這些大對象將被插入到數據庫中,但只有一個屬性在改變。將改變的屬性不是主鍵。第一次SaveChanges成功,但隨後的失敗,「ObjectStateManager中已存在一個具有相同鍵的對象.....」。這裏是代碼的流程:EF4添加多個實體(在ObjectStateManager中已存在具有相同密鑰的對象)

//create the entity and set the properties that don't change 
    TheLargeObject obj = new TheLargeObject(); 
    obj.Prop1 = 
    obj.Prop2 = 
    ... 
    obj.Prop20 = 

    //create a list of values that differ between each entity 
    List<int> validIds = new List<int>(); 

    private static void SaveToDatabase(TheLargeObject obj, List<int> validIds) 
    { 

     foreach (int id in validIds) 
     { 
      //this is the only property that changes 
      obj.KeyId = id; 

      //make a copy - do we really need this? 
      TheLargeObject newobj = new TheLargeObject(); 
      newobj = obj; 

      using(Entities objContext = new Entities()) 
      { 
       objContext.TheLargeObjects.AddObject(newobj); //ERROR: An object with the same key already exists in the ObjectStateManager. 
       objContext.SaveChanges(); 
      } 
     } 
    } 

我剛剛開始接觸EF4,所以我可能是錯誤的方式去了解這一點。 謝謝

+0

你爲什麼不接受答案? – Sampath 2016-08-29 07:57:49

回答

8

我不確定你想在這裏做什麼。主要是這種說法使我困惑:

一堆這些大對象將被插入數據庫,但只有一個屬性在他們改變。

一個對象(即插入)怎麼可以改變?如果它是新的,有什麼改變?

模型中的所有實體都有一個實體密鑰,它通常是數據庫端的主鍵。

我認爲你在做什麼是.AddObject,當你應該做.Attach

這裏是你如何INSERT一個新的對象:

var newFoo = new Foo(); 
ctx.Foos.AddObject(newFoo); 
newFoo.SaveChanges(); 

這裏是你如何UPDATE現有對象:

var existingFoo = ctx.Foos.SingleOrDefault(x => x.Id == 1); // or however you want to get it 
existingFoo.Name = "Changed foo"; 
newFoo.SaveChanges(); 

或者,如果你有一個分離實體:

var existingFoo = new Foo(); 
existingFoo.Name = "Foo name"; 
ctx.Foos.Attach(existingFoo); 
ctx.SaveChanges(); 

所以,我認爲在你的榜樣,你的代碼應該簡單地:

objContext.TheLargeObjects.Attach(newObject); 
objContext.SaveChanges(); 

概括地說,如果你有,你是正已經存在於數據庫中的實體,並已構建了實體手動使用.Attach。如果您的品牌打出新對象,請使用.AddObject

但是,爲了安全起見 - 您可以再次獲取對象,進行所需的更改,然後執行.SaveChanges()

.Attach.Attach通常用於諸如網站等無狀態場景,其中對象不會保存在請求之間的圖形中,因此需要更改我們需要的.Attach,或者在進行更改之前再次檢索對象。

希望這會爲你清除它。

+0

感謝您回覆並提供有關混淆的提示。這將是一個新的對象,所以我想要一個插入而不是更新。所以.Attach不會在我的情況下工作,因爲實體不會在數據庫中。創建對象是很耗時的(因爲有大量的屬性),因此我想要一種方法來只更改一個屬性,然後再執行savechanges()。我終於想出了使用上下文生命週期的正確方法,然後.AddObject開始工作。 – 2010-11-18 21:06:08

+0

那你把它分類好了嗎?令人困惑的是,你仍然在說「我想要一種方法來改變這個屬性」,再次,如果它是新對象,我很困惑它會改變什麼?或者你的意思是你只想設置新對象的一個​​屬性,並將其添加到數據庫中。如果它是一個新的對象,你應該使用'.AddObject'。那麼排序? – RPM1984 2010-11-18 22:28:03

+0

是的,它現在排序。我的意思是隻設置一個屬性並將其發送回數據庫。 – 2010-11-19 03:44:16

相關問題