对多个表的实体组联接

问题描述 投票:1回答:3

我正在尝试使用into而不是group by在具有一对多关系的多个表上执行组联接。但是有些事情是不对的。我得到用户具有的每个角色的重复记录。

from compUsr in Repository.All<CompanyUser>()
join usr in Repository.All<User>() on compUsr.UserId equals usr.Id
join usrRole in Repository.All<UserRole>() on usr.Id equals usrRole.UserId
join role in Repository.All<Role>() on usrRoles.RoleId equals role.Id into roles
    select new UserDTO()
    {
        Id = usr.Id,
        Email = usr.Email
        Roles = roles.Select(r => new RoleDTO()
        {
            Id = r.Id
        })
    }

[如果我删除角色表上的联接,并将into语句放在UserRole上,则分组的工作方式就像一个超级按钮,但UserRole只是一个链接表,因此Role表是我感兴趣的表。想法如何尽可能简单地分组?谢谢!

c# entity-framework linq-to-entities
3个回答
3
投票
from compUsr in Repository.All<CompanyUser>()
join usr in Repository.All<User>() on compUsr.UserId equals usr.Id
join usrRole in Repository.All<UserRole>() on usr.Id equals usrRole.UserId
join role in Repository.All<Role>() on usrRoles.RoleId equals role.Id
group new { usr, role } by usr into grp
                    select new
                    {
                        Id = grp.Key.Id,
                        Email = grp.Key.Email,
                        Roles = grp.Select(r => new RoleDTO()
                        {
                            Id = r.role.Id
                        })
                    };

1
投票

导航属性的存在是有原因的。它们使代码更加简洁明了。

有了导航属性,这很容易:

from usr in context.Users // or Repository.All<User>()
select new UserDto
{
    Id = usr.Id,
    Email = usr.Email,
    Roles = usr.UserRoles.Select(ur => ur.Roles)
               .Select(r => new RoleDTO()
                            {
                                Id = r.Id
                            }
}

我不知道为什么也加入CompanyUser(您似乎没有使用它),但是如果需要,您应该在此处开始查询并使用导航属性来到达其他实体。] >

此外,我假设您在Role中还有更多的RoleDto属性。如果不是,则无需选择Role实体,因为UserRoles已包含RoleId

所以由您决定。您可以信奉一个信条,即存储库调用的作用范围应恰好是一个实体(“单一责任”的非常狭义的定义),或将导航属性用于其发明目的,并考虑对子项负责的汇总根它封装。


0
投票
from compUsr in Repository.All<CompanyUser>()
join usr in Repository.All<User>() on compUsr.UserId equals usr.Id
join usrRole in Repository.All<UserRole>() on usr.Id equals usrRole.UserId
join role in Repository.All<Role>() on usrRoles.RoleId equals role.Id
group new { usr, role } by usr into grp
                    select new
                    {
                        Id = grp.Key.Id,
                        Email = grp.Key.Email,
                        Roles = grp.FirstOrDefault().role.Id
                    };
© www.soinside.com 2019 - 2024. All rights reserved.