长期使用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; }
}
答案 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()让这一切都发生了,谢谢大家的帮助。