2012-09-11 103 views
1

我對這個EF相當陌生,但我認爲我正在取得進展。無論如何,它似乎我不知道如何更新對象是RELATED由一個外鍵。ASP.NET C#實體框架 - 如何正確更新外鍵?

我DbRelation是: enter image description here

而且我試圖更新一個成員LANGUAGEID,這裏是我調用上下文:

public class ManagerBase 
    { 
     private static NoxonEntities _entities = null; 

     public NoxonEntities Entities 
     { 
      get 
      { 
       if (_entities == null) 
        _entities = new NoxonEntities(); 

       return _entities; 
      } 
     } 
    } 

有很多事情我都試過了。這裏是一個:

1)

MemberManager currentMemberManager = new MemberManager(); 
var Mem = currentMemberManager.MyEntities.Member.SingleOrDefault(c => c.Id == 2); 
var Lang = currentLanguageManager.Entities.Language.SingleOrDefault(c => c.Id == 1); 

      Mem.Language = Lang; 
//Or 
      Mem.LanguageId = Lang.Id; 
currentMemberManager.Save(Mem); 

在appreach 1,我得到這樣

The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship. 

2錯誤)

//Managers uses ManagerBase class as a Base class 
MemberManager currentMemberManager = new MemberManager(); 
currentMemberManager.Save(Globals.CurrentMember.Id, Globals.CurrentLanguage.Id); 
//These Global objects coming from a Http Session 
//You may also say not to keep whole member object in session which I'll not after I figure this out 

Here is my SAVE method and where I have the actual problem: 

public void Save(Member entity) 
     { 
      var Data = base.Entities.Member.First(c => c.Id == entity.Id); 
        if (Data != null) 
        { 
         Data = entity; 
         base.Entities.SaveChanges(); 
        } 
       } 
      } 

在appreach 1,我得到一個錯誤在EF模型中的代碼edmx文件

[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] 
     [DataMemberAttribute()] 
     public global::System.Int32 LanguageId 
     { 
      get 
      { 
       return _LanguageId; 
      } 
      set 
      { 
       OnLanguageIdChanging(value); 
       ReportPropertyChanging("LanguageId"); 
       _LanguageId = StructuralObject.SetValidValue(value); 
       ReportPropertyChanged("LanguageId"); 
       OnLanguageIdChanged(); 
      } 
     } 

和錯誤是

Object reference not set to an instance of an object. 

顯然我在與EF走錯了路。

你能幫我,並顯示如何正確更新關係Id(ForeignKeyId)?

非常感謝。

+3

靜態數據上下文是一個很大很大的大大不。可能不是你的錯誤,但我想指出這一點。 – Arran

+0

你似乎有兩個經理......這是否意味着你有兩個上下文。如果是這種情況,則不能混合來自兩個上下文的實體 – tschmit007

+0

謝謝Arran指出了這一點。 –

回答

6

是的,您正在以許多錯誤的方式使用EF。首先,正如Arran所指出的,你永遠不應該讓你的數據上下文保持靜態。我知道這似乎更容易,但這是一個巨大的問題,因爲數據上下文被設計爲經常創建和銷燬。

如果您不這樣做,那麼對象圖將繼續增長,直到應用程序池最終耗盡,此外還可能遇到併發訪問的各種問題。靜態對象在所有線程之間共享,因此想象一下,如果兩個用戶同時使用您的應用程序,他們都將使用相同的數據上下文,並會相互踩踏。

其次,你正在使用一個單身人士,這是一個最令人厭惡的模式之一,原因很多。他們有他們的用途,但他們比大多數人使用它們要少得多。

第三,根據錯誤消息,聽起來您的數據模型可能與您的EF模型不同步,因此它變得困惑並拋出異常。你是否修改了數據庫結構而不更新ef模型?請記住,重新生成並不總是更新所有內容,有時您必須手動更新它,或者刪除對象並重新添加它們。

四,你真正的問題(相信我,我已經奠定了的人也是現實的問題,那WILL咬你在某一點後)就在於此代碼:

var Data = base.Entities.Member.First(c => c.Id == entity.Id); 
if (Data != null) 
{ 
    Data = entity; 
    base.Entities.SaveChanges(); 
} 

您必須首先意識到的是,EF返回跟蹤對象,這些對象在EF中具有引用並跟蹤發生的更改。你在這裏做的是得到一個對象,然後扔掉它,並用傳入的未跟蹤對象替換它。

您必須更新從第一個方法返回的對象,而不是將其替換爲一個新的。

+0

嗯。我明白你的觀點,我現在開始嘗試修改我的代碼。對你的問題:我的EF模型是最新的。實際上,在我發佈這個問題之前,我重新創建了整個事情。謝謝。我可能需要再次回到這個問題。但我希望我不會。 –