2014-11-09 90 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();