2014-11-09 97 views
0

我有4個表,UserCredentialUserProfileUserRolesRoleLINQ的多對多關係加入

var user = (from uc in Db.UserCredentials 
       join up in Db.UserProfiles on uc.UserId equals up.UserId 
       join ur in Db.UserRoles on uc.UserId equals ur.UserId 
       select new { 
        Credetial = uc, 
        Profile = up, 
        Roles = Db.Roles.Where(r => r.RoleId == ur.RoleId)}) 
       .FirstOrDefault(); 

UserRoleUserIdRoleId,使用戶可以擁有多個角色。

上述代碼生成的查詢似乎效率不高。任何人都可以提出更好的代碼

+0

EF會自動爲關係創建導航屬性,因此您不需要使用連接。 – 2014-11-09 05:26:09

+0

您將EF和LINQ指示爲SQL。你在用哪個?每個生成的SQL可能會有很大的不同。發佈生成的SQL並指出您覺得效率低下的地方。無論如何,考慮把它看作一個對象圖,而不是用連接來設置,你可能會發現一個更好的選擇。 – 2014-11-10 01:30:47

回答

0

首先,由於我們擔心性能,請確保您的數據庫在所有這些UserId和RoleId列上都有索引。

由於您有多個UserRoles,包括它在連接中浪費地增加了查詢的基數,然後調用FirstOrDefault將其拉回到一。一?你沒有展示你如何選擇一個特定的用戶,但我會留給你解決,除非它在你的一個數據源中被過濾。

此外,匿名對象上的角色屬性:每次觸摸它時,都會觸及數據庫。這很可能是性能問題的根源。如果緩存該信息是可以接受的,則用ToList()調用完成子查詢將是謹慎的。

該子查詢本身可能是另一個麻煩來源,特別是如果使用ToList - 它將是另一次到數據庫的行程,所以請確保將主查詢的基數保持爲低以控制行程數。

var user = (from uc in Db.UserCredentials 
      join up in Db.UserProfiles on uc.UserId equals up.UserId 
      //where uc.UserId == somePassedInUserId /* add this line if your datasources aren't filtered */ 
      select new { 
       Credetial = uc, 
       Profile = up, 
       Roles = (from ur in Db.UserRoles join r in Db.Roles on ur.RoleId equals r.RoleId 
          where ur.UserId == uc.UserId select r).ToList() 
      .FirstOrDefault();