2009-01-24 95 views
12

我試圖在實體框架模型中定義兩個實體(一個映射到一個表,另一個映射到一個視圖 - 使用DefinedQuery)之間的1:1關聯。 試圖在設計器中爲此定義映射時,它使我選擇(1)表或視圖來將關聯映射到。我應該選擇什麼?我可以選擇兩個表中的任意一個,但是我不得不爲這個關係的每一端選擇一個來自該表(或視圖)的列。我希望能夠從一個表中爲聯合的一端選擇一個列,並在另一個表中爲聯合的另一端選擇一個列,但是沒有辦法做到這一點。定義實體框架1:1協會

在這裏,我選擇映射到「DW_ WF_ClaimInfo」視圖,它迫使我從該視圖中選擇兩列 - 關係的每一端。

我也試過在XML手動定義如下映射:

<AssociationSetMapping Name="Entity1Entity2" TypeName="ClaimsModel.Entity1Entity2" 
    StoreEntitySet="Entity1"> 
    <EndProperty Name="Entity2"> 
    <ScalarProperty Name="DOCUMENT" ColumnName="DOCUMENT" /> 
    </EndProperty> 
    <EndProperty Name="Entity1"> 
    <ScalarProperty Name="PK_DocumentId" ColumnName="PK_DocumentId" /> 
    </EndProperty> 
</AssociationSetMapping> 

但是這給: 錯誤2010:指定爲該MSL中MetadataWorkspace不存在的部分列「文件」 。 似乎它仍然期望兩列都來自同一張表,這對我來說沒有任何意義。

而且,如果我選擇的每一端,例如:

<AssociationSetMapping Name="Entity1Entity2" TypeName="ClaimsModel.Entity1Entity2" 
    StoreEntitySet="Entity1"> 
    <EndProperty Name="Entity2"> 
    <ScalarProperty Name="DOCUMENT" ColumnName="PK_DocumentId" /> 
    </EndProperty> 
    <EndProperty Name="Entity1"> 
    <ScalarProperty Name="PK_DocumentId" ColumnName="PK_DocumentId" /> 
    </EndProperty> 
</AssociationSetMapping> 

相同的密鑰然後我得到:

Error 3021: Problem in Mapping Fragment starting at line 675: Each of the following 
columns in table AssignedClaims is mapped to multiple conceptual side properties: 
    AssignedClaims.PK_DocumentId is mapped to 
    <AssignedClaimDW_WF_ClaimInfo.DW_WF_ClaimInfo.DOCUMENT, 
    AssignedClaimDW_WF_ClaimInfo.AssignedClaim.PK_DocumentId> 

什麼我沒有得到?

+3

有沒有一種方法可以重新發布該圖像?我有同樣的問題,但我不確定我們的設計是否相同。 – 2010-04-08 16:10:05

回答

6

您必須選擇包含外鍵的表。下一步是從實體中刪除外鍵,因爲它已經使用您剛剛創建的關係表達過。

例子:

table A 
------- 
A_ID int 
B_ID int 


table B 
------- 
B_ID int 

在這種情況下,你會在設計中選擇表A,因爲它包含的外鍵。此後,您需要從A實體中刪除B_ID。

-3

不能確定是否有答案,但對於實體框架,我總是在每個表中創建一個主鍵(即使我不需要它)。例如:

  • 表顧客已經CustumerID作爲主鍵
  • 桌產品已作爲產品ID當然主鍵
  • 表順序使用客戶ID +的ProductID作爲主鍵。那麼,我也創建一個本地主鍵:OrderID。
0

我正在處理遺留應用程序,所以添加一個額外的主鍵不是我的選擇。我所要做的就是將它映射爲1:(0或1)而不是1:1,以使其起作用。例如,如果我有兩個表,說明Customer和CustomerDetails都有一個名爲CustomerID的主鍵。要創建關聯,我必須將其設置爲1客戶可以關聯(0或1)CustomerDetails記錄。 Eveytime你插入一個客戶,確保也插入CustomerDetails,以便您可以保持1:1。

0

我同意這樣設置的方式似乎違反直覺。對於任何慢(像我一樣)得到driAn的答案的人: 根據以下論壇帖子,我記得我們正在處理一個實體,而不是直接處理表格。該協會位於實體(可以對錶格建模,但不一定)。

http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/2823634f-9dd1-4547-93b5-17bb8a882ac2/

實體框架關聯PROPERTIES表列。這就是爲什麼我們必須刪除「外鍵」PROPERTY上的ENTITY(注意:我們不刪除表列)。以引用列代碼,(使用ENTITY建模表A &表B的給定的例子),你會寫這樣的事:

variable_A = tableAs.A_ID 
variable_B = tableAs.tableBs.B_ID 

第二分配是使用在所定義的關聯實體獲取數據。沒有PROPERTY在表A上稱爲「B_ID」。

這就是所有假設我理解它:)。現在對我來說,這至少是正確的知識產權。

:-Dan

0

首先在數據庫中創建一個外鍵,然後從數據庫中創建協會或更新模型。

0

在實體框架中,在概念設計中不應該有外鍵。我相信現在允許在EF4中進行調整(有些調整),但在EF3.5中,它無法完成。

要解決這個問題,只需刪除表示EF設計器中外鍵的所有屬性即可。不要刪除主鍵!

如果您再獲得「關聯端未映射..」錯誤,請參閱(我的回答)this post

0

當我試圖在主鍵上連接的兩個表之間執行一對一操作時,我收到了同樣的錯誤。 (不,我沒有設計數據庫)。所以,刪除FK的解決方案不起作用 - FK也是PK,所以你不會刪除它。作爲一個實驗,我將協會的一個方面改爲0..1,並且瞧,模型編譯了W/O錯誤。我使用EF3.5

0

簡單來說,我做了以下內容:

  1. 與一列主鍵(PK)創建表。
  2. 使用外鍵(FK)在列上創建視圖。 或反之亦然。
  3. 在edmx Diagram Designer中創建了一個關聯。
  4. 編譯代碼。

在XAML元數據代碼中,具有PK的父實體將顯示子視圖實體,該子實體可以被關聯以綁定項目。

0

經過幾乎整整一天的工作,我找到了它!事實上,我發現了兩種不同的方法來解決這個問題,假設我有克雷格遇到的同樣的問題。

首先,driAn的回答並不能真正幫助(再次,如果克雷格有同樣的問題,我有),因爲這個問題是存在於表A的主鍵沒有單獨的外鍵是確切的表B的主鍵相同!特別是在我的情況,我使用的視圖和表格,而不是兩個表:

table A 
------- 
A_ID int 
col1 int 
col2 int 

view A_extra 
------- 
A_ID int 
col3 int 

因此,這裏有我找到了解決方案:

1映射到兩個不同的實體,但使用黑客。因此,driAn的答案的整個問題是,我們沒有單獨的外鍵列映射到,然後我們可以從屬性中刪除(我們不能從屬性中刪除它,因爲它是視圖的主鍵A_extra !)。因此,黑客是出奇​​的簡單,一旦你意識到這一點:編輯A_extra簡單地創建A_ID的副本,並使其成爲替身外鍵:

table A 
------- 
A_ID int 
col1 int 
col2 int 

view A_extra 
------- 
A_ID int 
A_FK_ID int   
col3 int 

A_FK_ID僅僅是在視圖的定義爲「A_ID爲A_FK_ID」 SQL,它將始終具有與A_ID完全相同的值。

現在,對於實體框架,這是一個非常熟悉的場景。只需創建1對1關聯,將關聯映射到A_extra,然後將表A中的屬性A_ID映射到A_FK_ID,將A_extra中的屬性A_ID映射到A_ID。根據EF,現在您不再讓同一列執行雙重任務了!然而,有趣的是,A_FK_ID將始終與A_extra中的A_ID相同。

現在您擁有A_extra的導航屬性,並且col3可以訪問,就像您期望的那樣。更好的是,你仍然可以本地更新table_A,因爲EF認爲它是一個表(如果你從這個組合中創建了一個單一的視圖並將它導入到EF中,那麼你不能在本地更新它)。

2.將表格和視圖映射到單個實體。您不需要對此解決方案進行破解,而且更好,因爲您無需通過導航屬性即可訪問col3。

要獲得此配置,請將A和A_extra同時添加到EF。將Aero中的col3複製並粘貼到A中,以便您現在擁有位於A中的未映射屬性「col3」,而A_extra中沒有任何內容。現在轉到A的映射並添加A_extra作爲要映射到的視圖(以便實體「A」現在映射到表「A」和視圖「A_extra」)。將屬性col3(在實體A中)映射到列col3(在視圖A_extra中)。 現在您可以看到如何顯示EF如何連接兩個以創建單個實體:將A_extra中的列A_ID映射到實體A中的屬性ID。如果您注意到,現在您將兩列映射到相同的屬性。這是可以的,因爲它們代表着同樣的事情,而且EF知道如何加入該專欄。

現在,要完成清理工作,必須在設計器中刪除浮動實體「A_extra」。 (您可能想要確保它不再被映射到查看A_extra,只是爲了確保它不會消除A_extra的商店映射 - 我希望它不會因爲實體A現在映射到它)。現在,您應該能夠從實體A構建並訪問col1,col2和col3!

很酷的事情是你可以更新數據到col1和col2,因爲它們映射到表(A),但EF會阻止你更喜歡它應該從更新col3,因爲它映射到一個視圖(A_extra )。這比在數據庫中合併視圖並導入數據庫更方便,因爲EF會阻止您更新的任何列,因爲它們全都來自視圖。

噢,我很高興我終於找到了這個工作。希望我的解決方案能幫助你們!

-Robert