2011-08-22 46 views
1

我有一個實體,稱爲Cost,其中有CostType如何在後面的代碼中設置導航屬性的值?

所需屬性的Cost類有一個GetNew()方法,將所有成本的默認值:

public static GetNew() 
{ 
    Cost cost = new Cost(); 
    foo.CostType = Lists.CostTypes.FirstOrDefault(); 
    // Other Default Values 

    return foo; 
} 

Lists.CostTypes是被拉到一個靜態列表從EF在啓動和在組合框中使用

我有問題在我的代碼中設置CostType,首先在GetNew()方法中設置它之後d。

例如,下面的代碼讀取Excel文件,並設置基於Excel文件中的列或null如果它不能找到一個匹配

Cost cost = Cost.GetNew(); 
cost.CostType = Lists.CostTypes.FirstOrDefault(t => t.Name == row[0].ToString()); 

我的問題是默認類型,保存操作過程中出現了以下錯誤:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

我的添加操作是這樣的:

public static void AddObject(EntityObject obj, string entitySetName) 
{ 
    context.AddObject(entitySetName, obj); 
    context.SaveChanges(); 
} 
  • 如果我在讀取excel文件時刪除手動設置Cost的代碼行,則保存工作正常。
  • 如果我更改代碼行以讀取Lists.Costs [2],它可以很好地保存。
  • 如果我刪除設置了默認值的GetNew()中的代碼行,我得到一個錯誤,告訴我違反了CostTypes的PK規則,這意味着它試圖插入成本類型。
  • 將顯示類型的組合框更改爲其他內容仍會給出相同的錯誤。
  • 在從excel文件加載成本後,當我更改類型並嘗試保存時,我的常規添加/編輯表單會引發相同的錯誤。如果我不加載一個Excel文件,它們工作正常。

我還在學習實體框架,但到目前爲止,它只是一個沮喪和頭痛的使用。有人知道我的問題是什麼以及我如何修復它?

編輯

這是一個被Slauma要求的信息。我保持它的簡單和排除不相關的對象

  • Costs是在一個表中,並CostTypes在另一個表。在數據庫中,Costs.TypeId列不允許爲空,並且是CostTypes的外鍵。兩個表的Id字段都是自動生成的。

  • 我的EF模型只是一個通用的,添加了兩個數據庫表。我對它做的唯一更改是重命名某些字段並刪除CostTypes.Costs導航屬性。這被大多數進口成本映射到他們的匹配CostType.Name

  • Excel文件,但它可能是在Excel文件中的字符串不匹配CostType,所以Lists.CostTypes.FirstOrDefault(t => t.Name == row[0].ToString()) can assign a NULL value to the Cost.Type property. That doesn't seem to be a problem though, because the form still comes up with the list of costs and their default selected items. Item's with a NULL CostType do not have an item selected in the CostType ComboBox`和觸發驗證錯誤,必須在保存前更正。

的代碼加載CostType列表是

public static List<T> GetList<T>(string sortProperty) 
    where T : EntityObject 
{ 
    using (var context = new TContext()) 
    { 
     return ApplyOrder<T>(context.CreateObjectSet<T>(), sortProperty, "OrderBy").ToList(); 
    } 
} 

ApplyOrder代碼可以發現here

的的GetList方法是從

public static class Lists 
{ 
    public static List<CostType> CostTypes { get; private set; } 

    static Lists() 
    { 
     CostTypes = DAL<CostEntities>.GetList<CostType>("Name"); 
    } 
} 
+0

'ClassA的class'實際上並不編譯,不是嗎?我希望這不是實際的代碼。 –

+0

'Type'實體是否引用了'ClassA'(一對一關係?)?你並沒有將'class.Type'設置爲'null',所以我猜這個例外並不是抱怨FK是屬於'ClassA.Type'的'null',而是一些其他的FK。 「Lists.Types」中的實體是否附加到上下文中? – Slauma

+0

@Slauma附帶'Lists.Types',如果我註釋掉第二次設置類型的行,則代碼運行正常。它是1:1的關係,我刪除了'Type.ClassA'導航屬性。和@亨克大聲笑否它不是實際的代碼 – Rachel

回答

2

我想通了....這是幾個不同的東西

創建新Cost和設置Type是增加成本,共享數據上下文的混合。如果成本不是在成本節省的名單中包括,或者它未能它的驗證錯誤,或抵消導入對話框的用戶,其成本仍然存在context.ObjectStateManager._addedObjects,儘管我從來沒有叫AddObjectAttachObject。一旦我意識到我開始冥想DeleteObject的成本不會被保存,並清除了我得到的第一個錯誤。

我得到的第二個錯誤(重複PK)是因爲我循環瀏覽了我的新費用,並在每個費用上撥打AddObjectSaveChanges。由於設置Cost.Type到連接的CostType被自動添加我的成本的情況下,第一成本得到節約,實際上將所有的新的成本轉嫁到數據庫,而第二個成本是想叫什麼EF看到作爲對象AddObject/SaveChanges已經存在

+0

「EntityObject」派生實體的屬性設置者中的關係管理使得事情難以遵循。很好,你最終解決了這個問題。 – Slauma

1

這裏稱爲是不是真的基於問題的相關信息,並在評論你的問題一個滿意的答案,但猜想的結構和開放的問題:

  • 首先:你的列表Lists.CostTypes包含顯然這是分離從上下文,你在後面添加和保存新對象因爲你有一個實體。block:using (var context = new TContext())您正在另一個上下文中檢索您的CostType實體。

  • 要告訴大家,這些CostType實體已經存在於數據庫中,你必須附加實體到你的第二個方面(context.CostTypes.Attach(costType))EF,你保存在您的改變(或您檢索使用相同的上下文中的方法列表)。我沒有在你的代碼中看到你這樣做。 (CostType是導航參考屬性,而不是外來鍵屬性,對不對?)

  • 就當沒有連接的CostType實體,你應該在你的數據庫中得到重複CostTypes因爲EF會考慮他們作爲新對象另一方面(在您爲Cost實體呼叫AddObject時,因爲EF始終會將分離實體的整個對象圖置於Added狀態,因此請插入數據庫中。您的工作示例中的數據庫中是否有重複的CostTypes?如果沒有,您的代碼片段中缺少重要的東西。

  • 最後一段假設CostType的關鍵字是在數據庫中自動生成的,如您所說。如果沒有,你會得到PK約束違反,而不是重複的實體。

  • 如果CostTypeCost的密鑰真的是自動生成的身份,我想知道您提到的PK違規可以從哪裏來。每次插入都會創建一個新的唯一主鍵。有可能永遠不會發生PK violaton。你能詳細顯示異常信息嗎?

  • 你檢查,你要保存所有Cost實體真的有一個非空CostType屬性(在用戶已經修復了所有驗證錯誤)?我看不出在你的代碼的任何其他可能的原因,你會得到你的「關係 - 可能 - 不被改變的-例外」,除了爲Cost對象CostTypenull之一至少。

+0

我想我明白了。這是一系列問題來自我對EF的缺乏經驗。我會在下面的答案中發佈。至於'using'語句,當我複製/粘貼該代碼時,我試圖使用非靜態/共享上下文。通常'Lists.CostTypes'附加到上下文。 – Rachel

相關問題