繁体   English   中英

如何使用Linq展平Entity Core多对多集合

[英]How to flatten Entity Core many-to-many collections using Linq

我不知道如何展平多个收藏夹。 实体用于使用实体框架核心创建的身份表。 它们包含我手动添加的导航属性,因为默认情况下Identity实体不包括这些属性(以及未显示的自定义模型构建器代码)

public class AppUser : IdentityUser<long> {

    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual List<AppUserRole> UserRoles { get; set; } = new List<AppUserRole>();

}

public class AppRole : IdentityRole<long> {

    public virtual List<AppUserRole> UserRoles { get; set; } = new List<AppUserRole>();

}

public class AppUserRole : IdentityUserRole<long> {

    public virtual AppUser User { get; set; }
    public virtual AppRole Role { get; set; }

}

这是我的仓库中的电话:

public async Task<IEnumerable<AppUser>> GetAllWithRoles() 
{
    return await _dbSet
        .AsNoTracking()
        .Include(u => u.UserRoles)
        .ThenInclude(ur => ur.Role)
        .ToListAsync();
}

上面的调用返回了此结构:

[
{
    "firstName": "XXXX",
    "lastName": "YYYYY",
    "userRoles": [
        {
            "role": {
                "userRoles": [],
                "id": 1,
                "name": "xxx",
                "normalizedName": "xxxx",
                "concurrencyStamp": "1617fe40-77e2-46cb-9c1c-df597d09775c"
            },
            "userId": 1,
            "roleId": 1
        }
    ]       
}
]

我想要的是:

[
{
    "firstName": "Alex",
    "lastName": "Florin",
    "RoleName": "Role1",
},
{
    "firstName": "Alex",
    "lastName": "Florin",
    "RoleName": "Role2",
},
{
    "firstName": "Jon",
    "lastName": "Smith",
    "RoleName": "Role1",
},
]

我想要的是整理集合。 我已经研究过SelectMany,但是我对Linq还是陌生的,所以我不知道如何将其用于众多收藏。 而且我知道调用函数的类型需要更改为与所需结构匹配的视图模型。

Automapper是另一种选择,因为我正在使用它来为更简单的实体创建视图模型,但是我不清楚如何设置使用该模型来平整多对多关系

不确定要精确展平的内容,以便从用户中选择所有角色

users.Select(p => p.UserRoles.Role)

从角色中选择所有用户

roles.Select(p => p.UserRoles.User)

编辑:

我认为这个例子将帮助您https://blog.oneunicorn.com/2017/09/25/many-to-many-relationships-in-ef-core-2-0-part-2-hide-as-ienumerable /

您的模型可能看起来像这样

public class AppUser : IdentityUser<long> {

    public string FirstName { get; set; }
    public string LastName { get; set; }

    private ICollection<AppRole> UserRoles{ get; } = new List<PostTag>();

    [NotMapped]
    public IEnumerable<string> RoleNames => UserRole.Role.Name

}

public class AppRole : IdentityRole<long> {
    private ICollection<AppRole> UserRoles{ get; } = new List<PostTag>();

    [NotMapped]
    public IEnumerable<AppRole> Users => UserRole.User
}

public class AppUserRole : IdentityUserRole<long> {
    public long UserID{ get; set; }
    public AppUser User { get; set; }

    public long RoleID { get; set; }
    public Role Role { get; set; }
}

我想到了。 一个问题是它排除了UserRoles = null的任何用户,但是由于可以保证所有用户在我们的系统中至少具有一个角色,所以应该没问题。

    public async Task<IEnumerable<UserEditorViewModel>> GetAllWithRoles() {

        return await _dbSet
            .AsNoTracking()
            .SelectMany(u => u.UserRoles)
            .Select(ur => new UserEditorViewModel {
                FirstName = ur.User.FirstName,
                LastName = ur.User.LastName,
                RoleName = ur.Role.Name
            })
            .ToListAsync();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM