0

实体框架的新手,试图找出一些东西。我有如下表格:

Users
---------
UserID
UserName

Roles
---------
RoleID
RoleName

UserRoles
---------
UserRoleID
UserID
RoleID

我正在使用存储库模式。这是一个存储库的示例(它们本质上都是相同的)

public class RoleRepository : IRoleRepository
{
    private AuthorizationContext context = new AuthorizationContext();
    public IQueryable<Role> Roles
    {
        get
        {
            return this.context.Roles;
        }
    }
    public bool Save(Role pRole)
    {
        if (pRole.RoleID == 0 || pRole.RoleID == null)
        {
            context.Roles.Add(pRole);
        }
        context.SaveChanges();
        return true;
    }
    public bool Delete(Role pRole)
    {
        context.Roles.Remove(pRole);
        context.SaveChanges();
        return true;
    }
}

现在,我想测试一个用户(通过 UserName)是否属于一个角色(通过 RoleName)。如何查询?我希望它是这样的,但它不起作用:

public bool IsUserInRole(string username, string roleName)
{
    var repo = new UserRepository();
    var user = repo.Users.FirstOrDefault(u => u.NetID == username && u.UserRoles.FirstOrDefault(r => r.Role.Name == roleName));
}

如何查询用户是否属于该角色?如果可能的话,我更喜欢使用谓词。

4

2 回答 2

1

我会使用这样的 .Any 函数:

public static bool IsUserInRole(string username, string roleName)
{
  using(var roleRepository = new RoleRepository())
  {
    return roleRepository.Roles.Any(r => r.RoleName == roleName && r.UserRoles.Any(ur => ur.User.UserName == username));
  }
}

这是一个示例控制台应用程序:

class Program
{
  static void Main(string[] args)
  {
    var users = new List<string> { "A", "B", "C", "D" };
    var roles = new List<string> { "User", "Admin", "Superuser"};

    //User A has roles: User, Admin, Superuser
    Debug.Assert(IsUserInRole(users[0], roles[0]) == true);
    Debug.Assert(IsUserInRole(users[0], roles[1]) == true);
    Debug.Assert(IsUserInRole(users[0], roles[2]) == true);

    //User B has roles: User, Admin
    Debug.Assert(IsUserInRole(users[1], roles[0]) == true);
    Debug.Assert(IsUserInRole(users[1], roles[1]) == true);
    Debug.Assert(IsUserInRole(users[1], roles[2]) == false);

    //User C has roles: User
    Debug.Assert(IsUserInRole(users[2], roles[0]) == true);
    Debug.Assert(IsUserInRole(users[2], roles[1]) == false);
    Debug.Assert(IsUserInRole(users[2], roles[2]) == false);

    //User D has no roles
    Debug.Assert(IsUserInRole(users[3], roles[0]) == false);
    Debug.Assert(IsUserInRole(users[3], roles[1]) == false);
    Debug.Assert(IsUserInRole(users[3], roles[2]) == false);

    Debugger.Break();
  }

  public static bool IsUserInRole(string username, string roleName)
  {
    using(var roleRepository = new RoleRepository())
    {
      return roleRepository.Roles.Any(r => r.RoleName == roleName && r.UserRoles.Any(ur => ur.User.UserName == username));
    }
  }
}

public interface IRoleRepository : IDisposable
{

}

public class RoleRepository : IRoleRepository
{
  private Context context = new Context();
  public IQueryable<Role> Roles
  {
    get
    {
      return this.context.Roles.AsQueryable<Role>();
    }
  }

  public void Dispose()
  {
      //Do nothing
  }
}

public class Context : IDisposable
{
  public IList<User> Users { get; set; }
  public IList<Role> Roles { get; set; }
  public IList<UserRole> UserRoles { get; set; }

  public Context()
  {
    //Generate Some Fake Data
    Users = new List<User>();
    Users.Add(new User { UserID = 1, UserName = "A" });
    Users.Add(new User { UserID = 2, UserName = "B" });
    Users.Add(new User { UserID = 3, UserName = "C" });
    Users.Add(new User { UserID = 4, UserName = "D" });

    Roles = new List<Role>();
    Roles.Add(new Role { RoleID = 1, RoleName = "User" });
    Roles.Add(new Role { RoleID = 2, RoleName = "Admin" });
    Roles.Add(new Role { RoleID = 3, RoleName = "Superuser" });

    UserRoles = new List<UserRole>();
    UserRoles.Add(new UserRole(1, Users[0], Roles[0]));
    UserRoles.Add(new UserRole(1, Users[0], Roles[1]));
    UserRoles.Add(new UserRole(1, Users[0], Roles[2]));
    UserRoles.Add(new UserRole(1, Users[1], Roles[0]));
    UserRoles.Add(new UserRole(1, Users[1], Roles[1]));
    UserRoles.Add(new UserRole(1, Users[2], Roles[0]));

    //User A has roles: User, Admin, Superuser
    //User B has roles: User, Admin
    //User C has roles: User
    //User D has no roles
  }

  public void Dispose()
  {
    //Do nothing
  }
}

public class User
{
  public int UserID { get; set; }
  public string UserName { get; set; }

  public IList<UserRole> UserRoles { get; set; }

  public User()
  {
    UserRoles = new List<UserRole>();
  }
}

public class Role
{
  public int RoleID { get; set; }
  public string RoleName { get; set; }

  public IList<UserRole> UserRoles { get; set; }

  public Role()
  {
    UserRoles = new List<UserRole>();
  }
}

public class UserRole
{
  public int UserRoleID { get; set; }

  public int UserId { get; set; }
  public User User { get; set; }

  public int RoleId { get; set; }
  public Role Role { get; set; }

  public UserRole(int id, User user, Role role)
  {
    UserRoleID = id;

    UserId = user.UserID;
    User = user;
    user.UserRoles.Add(this);

    RoleId = role.RoleID;
    Role = role;
    role.UserRoles.Add(this);
  }
}
于 2012-11-20T00:22:39.207 回答
1

这是您已经创建的修改后的“IsUserInRole”API:

    public bool IsUserInRole(string username, string roleName)
    {
        var repo = new UserRepository();
        return repo.Users.Any(u => u.UserName == username && u.UserRoles.Any(userrole => userrole.Role.RoleName == roleName));
    }

您的 API 的问题是 FirstOrDefault,它限制了导航属性。

于 2012-11-20T00:43:04.723 回答