Sam*_*tar 0 c# linq asp.net asp.net-identity
我有两个ASP.NET标识使用的类.一个是用户列表的支持类,另一个是角色.在数据库中有三个表.AspNetUsers,AspNetRoles和AspNetUserRoles.由于它们在实体框架中的映射方式,这三个映射到两个类:
public partial class AspNetUser
{
public AspNetUser()
{
this.AspNetUserClaims = new List<AspNetUserClaim>();
this.AspNetUserLogins = new List<AspNetUserLogin>();
this.AspNetRoles = new List<AspNetRole>();
}
public int Id { get; set; }
public virtual ICollection<AspNetRole> AspNetRoles { get; set; }
public virtual ICollection<AspNetUserClaim> AspNetUserClaims { get; set; }
public virtual ICollection<AspNetUserLogin> AspNetUserLogins { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和
public partial class AspNetRole
{
public AspNetRole()
{
this.AspNetUsers = new List<AspNetUser>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<AspNetUser> AspNetUsers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我有这个LINQ语句,我用来做一个数据报告.请注意,我只想获得与用户关联的第一个角色.这是我试过的:
var user = await db.AspNetUsers
.Where(u => u.AspNetRoles.Any(r => r.Id == roleId) || roleId == 0)
.Include(u => u.AspNetRoles)
.Select(u => new UserDTO
{
Email = u.Email,
RoleSingleId = u.AspNetRoles.SingleOrDefault(r => r.Id),
UserId = u.Id,
UserName = u.UserName
})
.ToListAsync();
Run Code Online (Sandbox Code Playgroud)
但这给了我两个错误,在r.Id下有一条蓝线
错误4无法将lambda表达式转换为委托类型'System.Func',因为块中的某些返回类型不能隐式转换为委托返回类型
错误5无法将类型'int'隐式转换为'bool'C:\ App\ab41\Admin1\WebRole1\Controllers\Web API - Data\UserController.cs 169 71 WebRole1
注意RoleSingleId声明为int,AspNetRoles的Id也是int.
小智 5
有一些问题.让我们从给出编译时错误的那个开始.
Run Code Online (Sandbox Code Playgroud)RoleSingleId = u.AspNetRoles.SingleOrDefault(r => r.Id),
SingleOrDefault
采用谓词,而不是投射.作为参数传递的是指示是否AspNetRole
应该考虑指定的条件.它的缩写u.AspNetRoles.Where(r => r.Id).SingleOrDefault()
.
那不是你想要的.投影是通过而Select
不是Where
通过写入来完成的,以便通过将其写为可以修复部分u.AspNetRoles.Select(r => r.Id).SingleOrDefault()
.
一旦你修复了它,下一个问题是SingleOrDefault()
如果找到多个项目就会抛出异常.那不是你想要的.您说您希望返回其中一个角色ID.就是FirstOrDefault()
这样.
巧妙回避的第三个问题SingleOrDefault()
是查询通常不支持.它将编译,但它会在运行时抛出异常,无论用户有多少角色,告诉你它只是不明白如何做到这一点,而你可能想要使用它FirstOrDefault()
.既然FirstOrDefault()
你应该使用它,那不是问题.
注意:您可能还想更改Select(r => r.Id)
为Select(r => (int?)r.Id)
:前者返回IEnumerable<int>
,后者返回IEnumerable<int?>
.如果用户没有角色(如果它完全有效),FirstOrDefault()
那么将返回0
前者,null
对于后者.null
这里可能更有意义.您需要以RoleSingleId
相同的方式调整类型.
归档时间: |
|
查看次数: |
1091 次 |
最近记录: |