C#LINQ lambda表达式

时间:2018-03-24 18:56:44

标签: c# entity-framework linq lambda

长期使用LINQ lambda表达式用户可能很容易,但我只是在这里碰壁...

我正在尝试获取具有特定ID的用户可以访问的所有Area对象。我正在使用实体框架,如果它因任何原因而重要。

context.AspNetUserRoles
    .Where(u => u.UserId == _currentUserId)
    .Select(ur => ur.AspNetRoles.RolePagePermissions.Select(pp => pp.Page.Area))
    .GroupBy(a => a.Select(g => g.Page.Select(gg => gg.Area)))
    .ToList()

我没有获得List<Area>,而是获得List<IGrouping<IEnumerable<IEnumerable<Area>>>

任何人都有关于如何轻松做到这一点的线索?

由于许多页面可以位于同一区域,并且角色连接到页面,因此以下代码返回许多重复区域(因为一个用户可以访问许多页面,因此返回每个页面的一个区域):

context.AspNetUserRoles.Where(u => u.UserId == _currentUserId).SelectMany(ur => ur.AspNetRoles.RolePagePermissions.Select(pp => pp.Page.Area)).ToList()

以下是测试模型:

public partial class Area
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Area()
    {
        this.Page = new HashSet<Page>();
    }

    public System.DateTime CreationDate { get; set; }
    public int CreationUser { get; set; }
    public int Id { get; set; }
    public string Title { get; set; }
    public byte Activated { get; set; }
    public string SimpleLineIcon { get; set; }
    public string ControllerName { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Page> Page { get; set; }
}

public partial class AspNetRoles
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public AspNetRoles()
    {
        this.AspNetUserRoles = new HashSet<AspNetUserRoles>();
        this.RolePagePermissions = new HashSet<RolePagePermissions>();
    }

    public string Id { get; set; }
    public string Name { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<AspNetUserRoles> AspNetUserRoles { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<RolePagePermissions> RolePagePermissions { get; set; }
}

public partial class AspNetUserRoles
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public string RoleId { get; set; }

    public virtual AspNetRoles AspNetRoles { get; set; }
    public virtual AspNetUsers AspNetUsers { get; set; }
}

public partial class AspNetUsers
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public AspNetUsers()
    {
        this.AspNetUserClaims = new HashSet<AspNetUserClaims>();
        this.AspNetUserLogins = new HashSet<AspNetUserLogins>();
        this.AspNetUserRoles = new HashSet<AspNetUserRoles>();
    }

    public string Id { get; set; }
    public string Email { get; set; }
    public bool EmailConfirmed { get; set; }
    public string PasswordHash { get; set; }
    public string SecurityStamp { get; set; }
    public string PhoneNumber { get; set; }
    public bool PhoneNumberConfirmed { get; set; }
    public bool TwoFactorEnabled { get; set; }
    public Nullable<System.DateTime> LockoutEndDateUtc { get; set; }
    public bool LockoutEnabled { get; set; }
    public int AccessFailedCount { get; set; }
    public string UserName { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<AspNetUserClaims> AspNetUserClaims { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<AspNetUserLogins> AspNetUserLogins { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<AspNetUserRoles> AspNetUserRoles { get; set; }
}

public partial class Page
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Page()
    {
        this.RolePagePermissions = new HashSet<RolePagePermissions>();
    }

    public System.DateTime CreationDate { get; set; }
    public int CreationUser { get; set; }
    public int Id { get; set; }
    public string Title { get; set; }
    public byte Activated { get; set; }
    public int AreaId { get; set; }
    public string SimpleLineIcon { get; set; }
    public string ActionName { get; set; }

    public virtual Area Area { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<RolePagePermissions> RolePagePermissions { get; set; }
}

public partial class RolePagePermissions
{
    public System.DateTime CreationDate { get; set; }
    public int CreationUser { get; set; }
    public int Id { get; set; }
    public string RoleId { get; set; }
    public int PageId { get; set; }
    public byte AccessAllowed { get; set; }
    public Nullable<System.DateTime> AccessAllowedByDate { get; set; }

    public virtual AspNetRoles AspNetRoles { get; set; }
    public virtual Page Page { get; set; }
}

3 个答案:

答案 0 :(得分:0)

在LinqToEntities中,Select方法将返回您在表达式中选择IQueryable类型(与LinqToObjects的想法相同,但是你有Function代替Expression作为Select方法的参数,它将返回IEnumerable。)

因此,如果您选择的属性类型为string,那么您将拥有IQueryable<string>,在您的情况下,您可以选择其他列表中的列表。您需要做的就是使用SelectMany只需解开Expression返回的集合,只为您提供一个包含所有项目的集合。

你最终会得到这样的东西:

List<Area> userAreas = context.AspNetUserRoles.Where(u => u.UserId == _currentUserId)
    .SelectMany(ur => ur.AspNetRoles.RolePagePermissions.Select(pp => pp.Page.Area)).ToList();

由于您已经知道用户的ID,并且您的实体模型与用户及其区域之间存在关系,因此无需使用GroupBy

答案 1 :(得分:0)

这应该是你想要的:

    context.AspNetUserRoles.Where(u => u.UserId == _currentUserId)
   .SelectMany(ur => ur.AspNetRoles.RolePagePermissions.Select(pp => pp.Page.Area));

不确定要通过群组来完成什么,但这会给出区域列表。

答案 2 :(得分:0)

我找到了一个返回所有可访问区域列表的解决方案:

context.AspNetUserRoles.Where(u => u.UserId == _currentUserId).SelectMany(ur => ur.AspNetRoles.RolePagePermissions.Select(pp => pp.Page.Area)).Distinct().ToList()

所以.Distinct()让这一切都发生了,谢谢大家的帮助。