7

我在更新實體框架實體中的外鍵時遇到問題。我正在使用自我跟蹤實體,並且有一個具有某些關係的實體,其中外鍵也作爲屬性存在(EF4的新功能之一)。鍵(整數)被標記爲可空和併發模式固定。實體框架4中允許可空的外鍵?

具體來說,我有一個與確認用戶有很多到0..1關係的警報實體。 (用戶可以確認多個警報,但只有零個或一個用戶可以確認警報)。

實體定義(簡體):

Alarm properties 
Id  Int32 non-nullable identity entity key 
UserId Int32 nullable concurrency mode fixed 
Alarm navigation properties 
User 0..1 multiplicity 

User properties 
Id  Int32 non-nullable identity entity key 
Name String non-nullable 

在我的自我跟蹤實體確認用戶ID是自動生成的,就像預期可空,但是如果我將用戶分配到一個已經持續報警運行ApplyChanges,自我跟蹤上下文擴展嘗試在EF上下文中設置原始值(空值)(在上下文擴展中的SetValue中),但由於EdmType的ClrEquivalentType是不可空的Int32而靜默跳過。

自動生成的擴展代碼:

private static void SetValue(this OriginalValueRecord record, EdmProperty edmProperty, object value) 
    { 
     if (value == null) 
     { 
      Type entityClrType = ((PrimitiveType)edmProperty.TypeUsage.EdmType).ClrEquivalentType; 
      if (entityClrType.IsValueType && 
       !(entityClrType.IsGenericType && typeof(Nullable<>) == entityClrType.GetGenericTypeDefinition())) 
      { 
       // Skip setting null original values on non-nullable CLR types because the ObjectStateEntry won't allow this 
       return; 
      } 
     } 

     int ordinal = record.GetOrdinal(edmProperty.Name); 
     record.SetValue(ordinal, value); 
    } 

當EF稍後嘗試更新我報警,我得到一個OptimisticConcurrencyException因爲它構建在它使用0(零)作爲原始的UPDATE語句的WHERE子句用戶外鍵值而不是正確的「爲空」。 (WHERE子句是EF樂觀併發機制的一部分,其中用「固定」併發模式標記的屬性的原始值再次被檢查數據庫中的屬性)。

EF的自我跟蹤實體中是否完全不支持可爲空的外鍵/基元類型? 如果沒有,我是否被迫使用虛擬實體而不是null或者是否有其他解決方法?

更新 我試圖重現該問題不STE,但普通的EF似乎處理樂觀併發以及對空的外鍵,所以這是一個STE的問題,而不是一個EF問題。 自我跟蹤實體存在很多問題,所以這裏出現故障並不奇怪。如果我找到可以在STE T4腳本中實施的解決方法,我會在此處發佈它。

回答

0

是的,可以爲null的外鍵肯定是允許的。我們在各地使用它們。您不會顯示數據庫或模型,因此很難確定問題所在,但聽起來好像實體框架無法找出涉及的某個表的主鍵。也許你沒有,也許是因爲其中之一是一種觀點?我在這裏猜測,因爲你沒有提供關於你在做什麼的很多信息。

+0

我很確定我的主鍵是確定的。 當我將可空引用實體更改爲新實體時,會發生此問題。這會導致原始實體引用(null)和密鑰(null)被存儲在原始值集合中。 當調用ApplyChanges時,嘗試將原始值從實體更改跟蹤器移至EF上下文,但由於EF上下文將密鑰的類型定義爲Int32,而非Nullable 作爲自跟蹤實體,因此無法將其指定爲null 。 – Holstebroe 2010-08-31 07:28:56

+0

可空列int列應該在你的CSDL中作爲int?'而不是'int'。嘗試使用新的(以前未映射的)表;你會看到的。自從創建模型後,你是否改變了可空性? – 2010-08-31 12:43:41

+0

我試圖創建一個新的實體「FooEntity」,沒有主鍵和一個名爲Foo的可空Int32。這是在CSDL產生: <的EntityType名稱= 「FooEntity」> <物業類型= 「的Int32」 NAME = 「富」 可空= 「真」/> 沒有的Int32?這裏。將Int32更改爲Int32?導致錯誤「值'Int32?'根據其數據類型'http://schemas.microsoft.com/ado/2008/09/edm:TPropertyType' – Holstebroe 2010-09-01 06:34:59