如何编写具有多对多关系的左连接

时间:2014-01-22 01:32:36

标签: linq c#-4.0 linq-to-entities entity-framework-5

我有以下实体:

实体:部门 DepartmentId(int) 名称(int) SuperiorDepartmentId(int,部门实体的外键) DepartmentPermissions(ICollection)

实体:DepartmentPermission DepartmentId(int) UserId(int) 权限(字符串) 部门(ICollection)

实体:用户 UserId(int) 名称(字符串) DepartmentPermissions(ICollection)

我需要在查询中返回所有部门(包括用户没有权限的部门)以及用户拥有权限时的权限名称。

DepartmentId | Name | SuperiorDepartmentId
1 | Sales | null
2 | Internal Sales | 1
3 | Marketing | null

DepartmentPermissions

DepartmentId | User Id | Permission
1 | 2 | r
2 | 2 | rw
1 | 3 | rw

用户

UserId | Name
1 | John
2 | Mary
3 | Paul

如果我要求用户Mary(id = 2)的数据,我们应该作为结果集:

DepartmentId | Name | SuperiorDepartmentId | Permission
1 | Sales | null | r
2 | Internal Sales | 1 | rw
3 | Marketing | null | null

我该怎么做?

1 个答案:

答案 0 :(得分:0)

我将假设存在导航属性Department.DepartmentPermissions

var query = from d in context.Departments
            select new { 
                         Department = d, 
                         Permissions = d.DepartmentPermissions
                                        .Where(dp => dp.UserId == 2)
                                        .Select(p => p.Permission)
                       };

var result = query.AsEnumerable()
                  .Select(x => 
                  new {
                        x.Department.DepartmentId,
                        x.Department.Name,
                        x.Department.SuperiorDepartmentId,
                        Permissions =
                          string.Join(", ", x.Permissions.DefaultIfEmpty("null")
                      }

首先收集原始数据(query),然后将最终结果组合在内存中。后者完成是因为EF不允许在LINQ查询中使用string.Join。您的数据结构允许一个部门中每个用户拥有多个权限,因此string.Join

如果您绝对确定始终有一个权限可以

Permission = d.DepartmentPermissions.Where(dp => dp.UserId == 2)
              .Select(p => p.Permission)
              .FirstOrDefault()
<{1>}中的

,已完成。