C# 实体框架深度查询多对多
刚接触实体框架,正在尝试解决一些问题。我有以下表格:C# 实体框架深度查询多对多,c#,.net,entity-framework,C#,.net,Entity Framework,刚接触实体框架,正在尝试解决一些问题。我有以下表格: Users --------- UserID UserName Roles --------- RoleID RoleName UserRoles --------- UserRoleID UserID RoleID 我使用的是存储库模式。下面是一个存储库示例(它们基本上都是相同的) 如何查询用户是否属于该角色?如果可能的话,我更喜欢使用谓词。我会使用。任何类似这样的函数: public static bool IsUserInRole
Users
---------
UserID
UserName
Roles
---------
RoleID
RoleName
UserRoles
---------
UserRoleID
UserID
RoleID
我使用的是存储库模式。下面是一个存储库示例(它们基本上都是相同的)
如何查询用户是否属于该角色?如果可能的话,我更喜欢使用谓词。我会使用。任何类似这样的函数:
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);
}
}
类程序
{
静态void Main(字符串[]参数)
{
var users=新列表{“A”、“B”、“C”、“D”};
var roles=新列表{“用户”、“管理员”、“超级用户”};
//用户A具有以下角色:用户、管理员、超级用户
Assert(IsUserInRole(用户[0],角色[0])==true);
Assert(IsUserInRole(用户[0],角色[1])==true);
Assert(IsUserInRole(用户[0],角色[2])==true);
//用户B具有以下角色:用户、管理员
Assert(IsUserInRole(用户[1],角色[0])==true);
Assert(IsUserInRole(用户[1],角色[1])==true);
Assert(IsUserInRole(用户[1],角色[2])==false);
//用户C具有以下角色:用户
Assert(IsUserInRole(用户[2],角色[0])==true);
Assert(IsUserInRole(用户[2],角色[1])==false);
Assert(IsUserInRole(用户[2],角色[2])==false);
//用户D没有角色
Assert(IsUserInRole(用户[3],角色[0])==false);
Assert(IsUserInRole(用户[3],角色[1])==false);
Assert(IsUserInRole(用户[3],角色[2])==false);
Debugger.Break();
}
公共静态bool IsUserInRole(字符串用户名、字符串角色名)
{
使用(var roleRepository=new roleRepository())
{
返回roleRepository.Roles.Any(r=>r.RoleName==RoleName&&r.UserRoles.Any(ur=>ur.User.UserName==UserName));
}
}
}
公共接口IRoleRepository:IDisposable
{
}
公共类角色库:IRoleRepository
{
私有上下文=新上下文();
公共可编辑角色
{
得到
{
返回this.context.Roles.AsQueryable();
}
}
公共空间处置()
{
//无所事事
}
}
公共类上下文:IDisposable
{
公共IList用户{get;set;}
公共IList角色{get;set;}
公共IList用户角色{get;set;}
公共上下文()
{
//生成一些虚假数据
用户=新列表();
添加(新用户{UserID=1,UserName=“A”});
添加(新用户{UserID=2,UserName=“B”});
添加(新用户{UserID=3,UserName=“C”});
添加(新用户{UserID=4,UserName=“D”});
角色=新列表();
添加(新角色{RoleID=1,RoleName=“User”});
添加(新角色{RoleID=2,RoleName=“Admin”});
添加(新角色{RoleID=3,RoleName=“Superuser”});
UserRoles=新列表();
添加(新用户角色(1,用户[0],角色[0]);
添加(新用户角色(1,用户[0],角色[1]);
添加(新用户角色(1,用户[0],角色[2]);
添加(新用户角色(1,用户[1],角色[0]);
添加(新用户角色(1,用户[1],角色[1]);
添加(新用户角色(1,用户[2],角色[0]);
//用户A具有以下角色:用户、管理员、超级用户
//用户B具有以下角色:用户、管理员
//用户C具有以下角色:用户
//用户D没有角色
}
公共空间处置()
{
//无所事事
}
}
公共类用户
{
public int UserID{get;set;}
公共字符串用户名{get;set;}
公共IList用户角色{get;set;}
公共用户()
{
UserRoles=新列表();
}
}
公共阶级角色
{
public int RoleID{get;set;}
公共字符串RoleName{get;set;}
公共IList用户角色{get;set;}
公共角色()
{
UserRoles=新列表();
}
}
公共类用户角色
{
public int UserRoleID{get;set;}
public int UserId{get;set;}
公共用户{get;set;}
public int RoleId{get;set;}
公共角色{get;set;}
公共用户角色(int-id、用户用户、角色)
{
UserRoleID=id;
UserId=user.UserId;
用户=用户;
user.UserRoles.Add(此);
RoleId=role.RoleId;
角色=角色;
role.UserRoles.Add(此);
}
}
以下是您已经创建的修改后的“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的问题是第一个默认值,它限制了导航属性。感谢您对FOD的澄清。非常有帮助!
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);
}
}
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));
}