[英]Ef Core filtering included query using uow and repository
I started creating a role-based security system in my WinForm application so I began with Form navigation (Permission Navigation) and this is my entity's我开始在我的 WinForm 应用程序中创建一个基于角色的安全系统,所以我从表单导航(权限导航)开始,这是我的实体
public partial class User
{
public User()
{
UsersToRoles = new HashSet<UsersToRole>();
}
public string Login { get; set; } = null!;
public string PasswordUser { get; set; } = null!;
public string? FullName { get; set; }
public string? Email { get; set; }
public int Id { get; set; }
public virtual ICollection<UsersToRole> UsersToRoles { get; set; }
}
public partial class Role
{
public Role()
{
UsersToRoles = new HashSet<UsersToRole>();
PermissionNavigations = new HashSet<PermissionNavigation>();
}
public int Id { get; set; }
public string Name { get; set; } = null!;
public virtual ICollection<UsersToRole> UsersToRoles { get; set; }
public virtual ICollection<PermissionNavigation> PermissionNavigations { get; set; }
}
public partial class UsersToRole
{
public int Id { get; set; }
public int IdUser { get; set; }
public int IdRole { get; set; }
public virtual Role IdRoleNavigation { get; set; } = null!;
public virtual User IdUserNavigation { get; set; } = null!;
}
public partial class Navigation
{
public Navigation()
{
PermissionNavigations = new HashSet<PermissionNavigation>();
}
public int Id { get; set; }
public string Page { get; set; } = null!;
public string Forms { get; set; } = null!;
public virtual ICollection<PermissionNavigation> PermissionNavigations { get; set; }
}
public partial class PermissionNavigation
{
public int Id { get; set; }
public int IdRole { get; set; }
public int IdNavigation { get; set; }
public virtual Navigation IdNavigationNavigation { get; set; } = null!;
public virtual Role IdRoleNavigation { get; set; } = null!;
}
This is my geniric GetAllIncluding method这是我的通用 GetAllIncluding 方法
public async Task<IEnumerable<T>> GetAllIncluding(params Expression<Func<T, object>>[] includeProperties)
{
try
{
IQueryable<T> query = dbSet;
foreach (Expression<Func<T, object>> includeProperty in includeProperties)
{
query = query.Include<T, object>(includeProperty);
}
return await query.ToListAsync();
}
catch (Exception ex)
{
throw new Exception($"{nameof(GetAllIncluding)} properties could not be included properly: {ex.Message}");
}
}
And this is how I use it in my PermissionNavigationService这就是我在 PermissionNavigationService 中使用它的方式
public async Task<IEnumerable<PermissionNavigationDto?>>
GetAllPermissionNavigationDetailsByUserAsync(int idUser)
{
var permissionNavigation = await unitOfWork.PermissionNavigations.GetAllIncluding(
x => x.IdNavigationNavigation,
x => x.IdRoleNavigation,
x => x.IdRoleNavigation.UsersToRoles.Where(x=>x.IdUser== idUser));
return mapper.Map<IEnumerable<PermissionNavigationDto?>>(permissionNavigation);
}
I know that this line of code only filtering UsersToRoles entity not PermissionNavigation entity我知道这行代码只过滤 UsersToRoles 实体而不是 PermissionNavigation 实体
x => x.IdRoleNavigation.UsersToRoles.Where(x=>x.IdUser== idUser)
The question is: What can be done to get all Permission Navigation related to specific user问题是:如何获得与特定用户相关的所有权限导航
Update1更新1
I am looking for something like this but in ef core我正在寻找类似的东西,但在 ef core
SELECT PermissionNavigation.[Id]
,PermissionNavigation.[IdRole]
,Roles.Name
,Navigation.Forms
,[IdNavigation]
,UsersToRoles.IdUser
FROM [SIM].[dbo].[PermissionNavigation]
INNER JOIN Roles on Roles.Id=IdRole
INNER JOIN Navigation on Navigation.id=IdNavigation
INNER JOIN UsersToRoles on UsersToRoles.IdRole=PermissionNavigation.[IdRole]
WHERE UsersToRoles.IdUser=@IdUser
Update2更新2
I appreciate all the help I received.我感谢我收到的所有帮助。
I decided to go this way:我决定走这条路:
When the user has successfully logged in, I catch the Id then I make a call to get all roles related to that user after that I make another call to get all permission navigation using role Id that I got earlier.当用户成功登录后,我会捕获该 ID,然后我调用以获取与该用户相关的所有角色,然后我再次调用以使用我之前获得的角色 ID 获取所有权限导航。
List<PermissionNavigationDto> navigationDtos = new();
var userRoles = await userToRoleService.GetUserRolesAsync(LoginUserDetails.Id);
foreach (var role in userRoles)
{
var navigation = await permissionNavigationService.GetPermissionNavigationByRoleIdAsync(role.IdRole);
navigationDtos.AddRange(navigation);
}
What you need is the SelectMany您需要的是SelectMany
//The userId concerned
int userId = 1;
//As an example, let's say you have your repository items below
List<User> users = new List<User>();
List<UsersToRole> userToRoles = new List<UsersToRole>();
List<Role> roles = new List<Role>();
//if you have to retrieve user
User myUser = users.SingleOrDefault(x => x.Id == userId);
//get all roleIds this user (userId = 1) belongs to
List<int> roleIds = userToRoles.Where(x => x.IdUser == userId).Select(us => us.IdRole).ToList();
//get the role objects, then the PermissionNavigations and flatten it out with SelectMany
List<PermissionNavigation> permissionNavigations = roles.Where(us => roleIds.Contains(us.Id)).Select(us => us.PermissionNavigations).SelectMany(x => x).ToList();
I hope this helps.我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.