从多表连接分组的 LINQ 子集结果

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

我有4张桌子:

USER:
-userKey
-userName

ROLE:
-roleKey
-roleDesc

PERMISSION:
-permissionKey
-permissionDesc

USERROLEPERMISSION:
-userKey
-roleKey
-permissionKey

这是数据库查询...

select
u.userKey,
u.userName,
r.roleKey,
r.roleDesc,
p.permissionKey,
p.permissonDesc
FROM
USER u
JOIN USERROLEPERMISSION urp  on u.userKey = urp.userKey
JOIN ROLE r on urp.roleKey = r.roleKey
JOIN PERMISSION p on urp.permissionKey = p.permissionKey

这是数据库结果...

userkey username                rolekey roledesc                permissionkey   permissiondesc
1       Captain Jack Sparrow    1       Admin                   1               Admin
1       Captain Jack Sparrow    2       Generic Data Access     5               Update
1       Captain Jack Sparrow    2       Generic Data Access     3               Read

我想运行 LINQ 查询来产生...

[
    {
        "userKey": 1,
        "userName": "Captain Jack Sparrow",
        "rolePermissionSet": [
            {
                "roleKey": 1,
                "roleDesc": "Admin",
                "permissionSet": [
                    {
                        "permissionKey": 1,
                        "permissionDesc": "Admin",
                    }
                ]
            },
            {
                "roleKey": 2,
                "roleDesc": "Generic Data Access",
                "permissionSet": [
                    {
                        "permissionKey": 5,
                        "permissionDesc": "Update",
                    },
                    {
                        "permissionKey": 3,
                        "permissionDesc": "Read",
                    }
                ]
            }
        ]
    }
]

我尝试了类似以下的操作,但它从未按照我想要的方式进行分组...将为每个用户/角色/权限组合提供单独的元素。我在考虑使用 group/by?但我无法得到正确的语法。我看过的所有样本都相当初级......

            var query =
                (from u in _dbContext.Users
                join urp in _dbContext.SAIMUserRolePermissions on u.UserKey equals urp.UserKey
                 select new UserRolePermissionSet
                 {
                     UserKey = u.UserKey,
                     UserName = u.UserName,
                     RolePermissionSet = (from rd in _dbContext.RoleDescriptions
                            where urp.UserKey == u.UserKey
                            where urp.RoleKey == rd.RoleKey
                            select new RolePermissionSet
                            {
                                RoleKey = rd.RoleKey,
                                RoleDescription = rd.RoleDescription,
                                PermissionSet = (from pd in _dbContext.PermissionDescriptions
                                              where urp.UserKey == u.UserKey
                                              where urp.RoleKey == rd.RoleKey
                                              where urp.RolePermissionKey == pd.RolePermissionKey
                                              select new RolePermissionDesc
                                              {
                                                  RolePermissionKey = pd.RolePermissionKey,
                                                  RolePermissionDescription = pd.RolePermissionDescription
                                              }).ToList()
                            }).ToList(),
                 }).ToListAsync();

这是模型和 dbcontext 详细信息...

    public DbSet<UserRolePermission> SAIMUserRolePermissions { get; set; }
    public DbSet<RoleDesc> RoleDescriptions { get; set; }
    public DbSet<RolePermissionDesc> PermissionDescriptions { get; set; }
    public DbSet<UserRolePermissionSet> UserRoles { get; set; }
    public DbSet<Participant> Participants { get; set; }
    public DbSet<User> Users { get; set; }

    modelBuilder.Entity<UserRolePermission>().ToTable("userrolepermission");
    modelBuilder.Entity<RoleDesc>().ToTable("role");
    modelBuilder.Entity<RolePermissionDesc>().ToTable("permission");
    modelBuilder.Entity<User>().ToTable("user");

    [Table("userrolepermission")]
    public class UserRolePermission
    {
        [Key()]
        [Column("userrolekey")]
        public long UserRoleKey
        {
            get; set;
        }

        [Required()]
        [Column("userkey")]
        public long UserKey
        {
            get; set;
        }

        [Required()]
        [Column("rolekey")]
        public long RoleKey
        {
            get; set;
        }

        [Required()]
        [Column("rolepermissionkey")]
        public long RolePermissionKey
        {
            get; set;
        }
    }
    
    [Table("role")]
    public class RoleDesc
    {
        [Key()]
        [Column("rolekey")]
        public long RoleKey
        {
            get; set;
        }

        [Required()]
        [Column("roledesc")]
        public string? RoleDescription
        {
            get; set;
        }
    }
    
    [Table("permission")]
    public class RolePermissionDesc
    {
        [Key()]
        [Column("rolepermissionkey")]
        public long RolePermissionKey
        {
            get; set;
        }

        [Required()]
        [Column("rolepermissondesc")]
        public string? RolePermissionDescription
        {
            get; set;
        }
    }
    
    public class UserRolePermissionSet
    {
        [Key()]
        public long UserKey
        {
            get; set;
        }

        public string? UserName
        {
            get; set;
        }

        public List<RolePermissionSet>? RolePermissionSet
        {
            get; set;
        }
    }

    [Table("user")]
    public class User
    {
        [Key()]
        [Column("userkey")]
        public long UserKey
        {
            get; set;
        }

        [Column("username")]
        public string? UserName
        {
            get; set;
        }
    }
linq group-by
1个回答
0
投票

好吧,看起来您没有适当的导航属性,并且需要

join


// request only what you need
var query =
    from u in _dbContext.Users
    join urp in _dbContext.SAIMUserRolePermissions on u.UserKey equals urp.UserKey
    join r in _dbContext.RoleDescriptions on urp.roleKey equals r.roleKey
    join p in _dbContext.PermissionDescriptions on urp.permissionKey equals p.permissionKey
    select new
    {
        u.UserKey,
        u.UserName,
        urp.RoleKey,
        r.RoleDescription,
        p.PermissionKey,
        p.PermissionDesc
    };

// materialize the query
var flattentResult = await query.ToListAsync(); 

// perform grouping to achieve desired result on the client side
var result = flattentResult
    .GroupBy(ug => new { ug.UserKey, ug.UserName })
    .Select(g => new UserRolePermissionSet
    {
        userKey = g.Key.UserKey,
        userName = g.Key.UserName,
        rolePermissionSet = g
            .GroupBy(rg => new { rg.RoleKey, rg.RoleDescription })
            .Select(rg => new RolePermissionSet
            {
                RoleKey = rg.Key.RoleKey,
                RoleDescription = rg.Key.RoleDescription,
                PermissionSet = rg.Select(p => new RolePermissionDesc
                {
                    RolePermissionKey = p.PermissionKey,
                    RolePermissionDescription = p.PermissionDesc
                })
            })
    })
    .ToList();
© www.soinside.com 2019 - 2024. All rights reserved.