我知道Code-First使用慣例進行模型綁定,並且這是list of conventions默認情況下可用(並且活動?)。如何用Entity Framework Code First確定多對多聯結表名稱?
它似乎的結表名了許多對許多關係的選擇是有點亂..
所引用公約的用於確定交會表名?用於確定該名稱的算法是什麼?
我知道Code-First使用慣例進行模型綁定,並且這是list of conventions默認情況下可用(並且活動?)。如何用Entity Framework Code First確定多對多聯結表名稱?
它似乎的結表名了許多對許多關係的選擇是有點亂..
所引用公約的用於確定交會表名?用於確定該名稱的算法是什麼?
我認爲,對於許多一對多連接表的名稱一般的規則是
ClassNameOfLeftEntity + PluralizedClassNameOfRightEntity
因此,如果第一個實體是User
,第二個是Role
連接表名字是UserRoles
。
這可能會受到刪除PluralizingTableNameConvention
影響,但我不確定。
更大的問題是確定什麼是「左」和什麼是「正確的」實體。我認爲它取決於幾乎隨機的因素,例如EF建立模型的順序,而順序依賴於實體之間的導航屬性以及您在派生上下文中編寫DbSet
的順序。出於這個原因,強烈建議用Fluent API明確定義連接表名稱。 EF模型中的小改動或改變上下文中組的順序可讓EF認爲名稱必須是RoleUsers
而不是前者UserRoles
。
這是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
查詢:
var user = context.Users.Include(u => u.Roles).Single(u => u.UserId == 1);
這將創建一個SQL JOIN在連接表的UserId
:ON Users.UserId = RoleUsers.UserId
。此連接不能使用連接表中的索引,而是會導致表掃描以檢索表中用戶的RoleIds行1,3和5。
這樣的查詢的性能更好的是將User
作爲左實體,將Role
作爲正確的實體,從而導致該對(UserId,RoleId)的聚集索引,這對於此類查詢的性能更好。 (當然,您可以在上面的示例中創建第二個索引以提高性能。)要實現此目標,您必須指定Fluent API的映射。
因此,明智地選擇左右實體並且不要將此決定留給EF是有意義的。