2011-12-14 5 views
2

私はCode-Firstがモデルバインディングの規則を使用しており、これはデフォルトで利用可能な(そしてアクティブな)list of conventionsであることを知っています。それは、多対多の関係のためのジャンクションテーブル名の選択が少しランダムであることを思わ多対多ジャンクション・テーブル名は、Entity Frameworkコード・ファーストでどのように決定されますか?

..ジャンクションテーブル名を決定するために使用される参照規則の

?その名前を決定するために使用されるアルゴリズムは何ですか?私が思う

答えて

3

、多対多の結合テーブル名の一般的なルールは

ClassNameOfLeftEntityです+ PluralizedClassNameOfRightEntity

だから、最初のエンティティはUserであり、第二は、テーブルに参加Roleある場合名前はUserRolesです。

これは、PluralizingTableNameConventionを削除すると影響を受ける可能性がありますが、わかりません。

大きな問題は、「左」とは何か、「正しい」エンティティは何かを判断することです。私は、EFがモデルを構築する順序と、エンティティ間のナビゲーションプロパティと、派生したコンテキストにDbSetを書いた順序に依存するという、ほぼランダムな要素に依存すると思います。このため、Fluent APIで明示的に結合テーブル名を定義することを強く推奨します。モデルの小さな変更やコンテキスト内のセットの順序を変更すると、EFは前のUserRolesの代わりに名前がRoleUsersでなければならないと考えることができます。

ここにはreference to a similar answerがあります。

編集

常に明示的に流暢APIと(それほどテーブル名の質問に関連しているが、左と何がどうあるべきかの質問に多くのない多対多マッピングを定義するためのもう一つの理由権利エンティティ)はパフォーマンスです。

結合テーブルには、少なくともSQL Serverでは、そのキーに複合主キーとクラスタ化インデックスがあります。今、テーブル名がRoleUsersだろうと想定し、左の実体はRoleあると、おそらくいくつかの開発者がコンテキスト内でアルファベット順にセットをソートすることを決めたので、右のエンティティがUser次のとおりです。

public DbSet<Role> Roles { get; set; } 
public DbSet<User> Users { get; set; } 

結合テーブルのエントリは次のようになります。

RoleId UserId 
---------------- 
1   1 
1   2 
2   1 
2   2 
3   1 
3   2 

ここで、おそらくアプリケーションのクエリの大半は、特定のユーザーの役割を取得することに関心があります。しかし、あなたは、しばしば、または決して関心のあるユーザーのためにすべてのユーザーを取得することは興味がありません。与えられたユーザの役割はIncludeで問い合わせることができます。ON Users.UserId = RoleUsers.UserId

var user = context.Users.Include(u => u.Roles).Single(u => u.UserId == 1); 

これは、結合テーブル内UserIdにSQLでJOINを作成します。この結合は、結合表の索引を使用することはできませんが、ユーザーのRoleIdsの表の行1,3および5を取り出すための表スキャンが行われます。

このようなクエリのパフォーマンスのためのより良いは、クエリのパフォーマンスのために優れているペアのためのクラスタ化インデックス(ユーザーID、RoleId)で得られた、右のエンティティとして左エンティティとしてUserRoleを有することです。 (もちろん、上記の例ではパフォーマンスを向上させるために2番目のインデックスを作成することができます)。これを実現するには、Fluent APIを使用してマッピングを指定する必要があります。

したがって、左右のエンティティを賢明に選択し、この決定をEFに残さないことが理にかなっています。

関連する問題