实体框架6:按角色解析用户权限(IdentityUserRole)

时间:2014-02-10 15:30:23

标签: entity-framework

我有一个实体更改其状态的进程,我希望获得当前用户可以转移到的状态,我有以下表达式,在评估时我得到 NotSupportedException 留言:

  

无法创建类型的常量值   'Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole'。只要   在此上下文中支持原始类型或枚举类型。

var user = db.Users.Single(...); //Successfully Retrieve the user
var states = db.StateTransitions
    .Join( db.RoleStateTransitions
        .Join( user.Roles,
            rst => rst.RoleID,
            ur => ur.RoleId,
            ( rst, ur ) => rst ),
        wst => wst.StateTransitionID,
        rst => rst.StateTransitionID,
        ( wst, rst ) => wst.FinalState ) ;

正如您所看到的那样,加入user.Roles(IdentityUserRole的集合)就是问题所在。前面的表达有什么问题?

1 个答案:

答案 0 :(得分:1)

问题是user.Roles是本地对象集合。 EF无法将本地对象转换为SQL(即使它们是映射对象)。但是你可以通过将本地集合简化为原始类型来使其工作:

var userRoleIds = db.Users.Where(u => u.UserId == id)
                    .SelectMany(u => u.Roles.Select(r => r.RoleId))
                    .ToList();

var states = from wst in db.StateTransitions
             join rst in db.RoleStateTransitions
                           .Where(x => userRoleIds.Contains(x.RoleId))
                 on wst.StateTransitionID equals rst.StateTransitionID
             select wst.FinalState;

或者甚至可能是一个查询:

var states = from wst in db.StateTransitions
             join rst in db.RoleStateTransitions
                 on wst.StateTransitionID equals rst.StateTransitionID
             join role in db.Roles
                 on rst.ROleId equals role.RoleId
             where role.Users.Any(u => u.UserId == id)
             select wst.FinalState;

(假设UserRole之间有多对多。