无法创建类型为"标识用户角色"的常量值。仅支持基元类型或枚举类型



在我的ASP.NET MVC 5应用程序中,我想列出用户的角色。我下载了一些似乎坏了的样本。基本上,我想要所选用户(而不是当前用户!)角色的角色ID和角色名称。

Roles为我提供了一个只有RoleId和UserId的IdentityUserRole对象。

Roles为我提供了一个Identity Role,其中包含所有应用程序角色的RoleId、RoleName等。

因此,我想要的是一个包含两个集合交集的结果集,同时保留完整的角色信息,这样我就可以同时使用它的角色ID和角色名称。

我尝试过Intersect(),但没有成功,因为两个对象的类型不同。我尝试了愚蠢的迭代风格,但得到了一个异常,说DAta阅读器已经激活了,所以我被难住了:(

我在LinQPad上尝试了以下操作(使用适当的功能和名称空间):

string UserName = "user@email.com";
ApplicationDbContext ctx = new ApplicationDbContext();
var allroles = ctx.Roles.OrderBy(r => r.Id);
allroles.Dump();    // dumps well, 6 roles
ApplicationUser user = ctx.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
var myroles = user.Roles;
myroles.Dump();     // dumps well, 3 roles
IEnumerable<IdentityRole> list = from roles in allroles
    join uroles in myroles
    on roles.Id equals uroles.RoleId
    select roles;
list.Dump();    // exception

虽然查询在执行过程中似乎不会产生错误,但无论我使用Dump()还是显式foreach(列表中的IdentityRole项),它的转储都会产生错误。在这种情况下,我得到的错误是

"无法创建类型为"Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole"的常数值。此上下文中仅支持基元类型或枚举类型"。

这里唯一的问题是,您没有调用立即执行查询的ToList()方法(所有内容都将保存在内存中)。

为了更好地理解,ToList()方法将IEnumerable<T>转换为List<T>

因此,您的代码将如下所示:

var allroles = ctx.Roles.OrderBy(r => r.Id).ToList();    
var myroles = user.Roles.ToList();

您可以使用尝试过的两种方法的组合,从ApplicationUserRoles属性中存在的上下文中获取角色。。。

var roles = ApplicationDbContext.Roles
                                .Where(ar => 
                                       ApplicationUser.Roles
                                                      .Select(ur => 
                                                              ur.RoleId)
                                                      .Contains(ar.RoleId));

您可以这样做:

 var rolesList = allroles.ToList().Join(myroles.ToList(), 
                                        left => left.Id, 
                                        right => right.RoleId, 
                                        (left,right) => left);

这种方式适用于不同的场景。

您正试图将内存中的列表myrolesIQueryableallroles连接,从而生成新的IQueryable:list。但是,这个新的IQueryable被翻译成SQL,所以myroles也必须被翻译成SQL。非基元类型的列表不支持此操作。

解决方案是加入两个IQueryable

var myroles = ctx.Users.Where(u => u.UserName == UserName).SelectMany(u => u.Roles);
var list = from role in allroles
           join urole in myroles
           on role.Id equals urole.RoleId
           select role;

相关内容

  • 没有找到相关文章

最新更新