2012-11-19 64 views
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; 
    } 
} 

現在,我想測試一下,看看如果用戶(通過用戶名)屬於角色(按角色名)。我如何查詢?我預計它是這樣的,但它不起作用:

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)); 
} 

我該如何查詢,看看用戶是否屬於角色?如果可能,我寧願使用謂詞。

回答

1

我會使用的功能。任何像這樣的:

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); 
    } 
} 
+0

很好的例子。我會研究這個。 – solidau

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,它限制了導航屬性。

+0

感謝您對FOD的澄清。很有幫助! – solidau