、多対多の結合テーブル名の一般的なルールは
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)で得られた、右のエンティティとして左エンティティとしてUser
とRole
を有することです。 (もちろん、上記の例ではパフォーマンスを向上させるために2番目のインデックスを作成することができます)。これを実現するには、Fluent APIを使用してマッピングを指定する必要があります。
したがって、左右のエンティティを賢明に選択し、この決定をEFに残さないことが理にかなっています。