私のデータモデルは、複合主キーと連想テーブルを持つ2つのテーブルを含みます。複合主キーの一部はテーブル間で共通です。
SitePrivilege
-------------
SiteId
PrivilegeId
UserSite
--------
SiteId
UserId
UserSitePrivilege
-----------------
UserId
SiteId
PrivilegeId
SitePrivilegeエンティティとUserSiteエンティティを作成しました。私はそれらの間の多対多関連をUserSitePrivilegeにマッピングしました。
<Association Name="UserSiteSitePrivilege">
<End Type="PrivilegeModel.UserSite" Multiplicity="*" Role="UserSite" />
<End Type="PrivilegeModel.SitePrivilege" Multiplicity="*" Role="SitePrivilege" />
</Association>
...
<AssociationSetMapping Name="UserSiteSitePrivilege" TypeName="PrivilegeModel.UserSiteSitePrivilege" StoreEntitySet="UserSitePrivilege">
<EndProperty Name="SitePrivilege">
<ScalarProperty Name="PrivilegeId" ColumnName="PrivilegeId" />
<ScalarProperty Name="SiteId" ColumnName="SiteId" />
</EndProperty>
<EndProperty Name="UserSite">
<ScalarProperty Name="SiteId" ColumnName="SiteId" />
<ScalarProperty Name="UserId" ColumnName="UserId" />
</EndProperty>
</AssociationSetMapping>
上記のコードでこのエラーが発生します。
テーブルUserSitePrivilegeの以下の各列は、複数の概念的なサイドプロパティにマッピングされます。UserSitePrivilege.SiteIdは、UserSiteSitePrivilegeSitePrivilege.SiteId、UserSiteSitePrivilege.UserSite.SiteIdにマッピングされます。
そこで、参照制約を追加しました。
<Association Name="UserSiteSitePrivilege">
<End Type="PrivilegeModel.UserSite" Multiplicity="*" Role="UserSite" />
<End Type="PrivilegeModel.SitePrivilege" Multiplicity="*" Role="SitePrivilege" />
<ReferentialConstraint>
<Principal Role="UserSite">
<PropertyRef Name="SiteId"/>
</Principal>
<Dependent Role="SitePrivilege">
<PropertyRef Name="SiteId"/>
</Dependent>
</ReferentialConstraint>
</Association>
...
<AssociationSetMapping Name="UserSiteSitePrivilege" TypeName="PrivilegeModel.UserSiteSitePrivilege" StoreEntitySet="UserSitePrivilege">
<EndProperty Name="SitePrivilege">
<ScalarProperty Name="PrivilegeId" ColumnName="PrivilegeId" />
<ScalarProperty Name="SiteId" ColumnName="SiteId" />
</EndProperty>
<EndProperty Name="UserSite">
<ScalarProperty Name="SiteId" ColumnName="SiteId" />
<ScalarProperty Name="UserId" ColumnName="UserId" />
</EndProperty>
</AssociationSetMapping>
今度はそれはこのエラーを生成します:
Principal Role UserSiteによって参照されるプロパティは、Relationship PrivilegeModel.UserSiteSitePrivilegeのリレーションシップ制約でPrincipal Roleによって参照されるEntityType PrivilegeModel.UserSiteのキーとまったく同じである必要があります。すべての主要プロパティがプリンシパルロールに指定されていることを確認してください。
この関係を正しくモデル化する方法
このような重複したFKは3.5 SP1ではサポートされていません。
すなわち
UserSitePrivilege
----------
UserId
SiteId
PrivilegeId
PK => UserId, SitedId, PrivilegeId
FK1 => UserId, SiteId
FK2 => SiteId, PrivilegeId
FK1はFK2と重なります。これはEF 4のBeta 2以降でサポートされる予定です。これはFKアソシエーション(Beta 2で利用可能)が独立アソシエーション(3.5 SP1および4.0 Beta 1で持っているもの)よりはるかに柔軟だからです。
FK協会の詳細については、この記事を参照してください。
それまでの間、あなたの唯一の選択肢はおそらくDefiningQueriesやCUD手続きなどの背後にあるこれらすべてを隠すことです。
主キーが複合キーの場合、すべての外部キー関係も参照用に複合キー全体(すべてのキー列)を使用する必要があります。これを回避する方法はありません。これはリレーショナルデータベースの基本原則です。デザイン、本当に。
これは、実際のデータ列から構成された複合キーではなく、主キーにメインテーブルの代替列を使用することを選択する主な理由の1つです。
更新:はい、あなたのコメントに基づいて、あなたは絶対に正しい - DBの設計はしっかりしています。 EFがこれに対処できない理由はよくわからない…。
マーク