英文:
EF Core - query is changing depending of the role
问题
我有两个角色,Admin(管理员)和Operator(操作员)。Admin可以看到所有行,Operator只能看到他插入的那些。
我可以使用 if-else
来实现这个功能。
public async Task<PagedResponse<TodoItemBriefDto>> Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken)
{
if(request.User.RoleId == "OPERATOR")
{
return await _context.Set<TodoItemExample>()
.Where(x => x.UserId == request.User.Id));
}
else
{
return await _context.Set<TodoItemExample>();
}
}
我在思考,是否有更加优雅的方法来实现这个功能?
英文:
I have two roles, Admin and Operator. Admin can see all rows, Operator only those which he inserted.
I can do this with if-else
public async Task<PagedResponse<TodoItemBriefDto>> Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken)
{
if(request.User.RoleId=="OPERATOR")
{
return await _context.Set<TodoItemExample>()
.Where(x => x.UserId== request.User.Id));
}
else
{
return await _context.Set<TodoItemExample>();
}
}
I am wondering, is there more elegant way to do this?
答案1
得分: 2
以下是您要翻译的内容:
What you have is fine but if by elegant, you mean less lines then you can move the condition into the where statement.
private const string AdminRole = "ADMIN";
public async Task<PagedResponse<TodoItemBriefDto>> Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken)
{
var userRole = request.User.RoleId;
return await _context.Set<TodoItemExample>()
.Where(x => userRole == AdminRole || x.UserId == request.User.Id));
}
If the user has the admin role then it won't filter the items that have the same user Id as the requesting user. This example assumes there are only two roles.
PS you should be using constant field members for known, unchanging strings as in the example above.
If you actually want to make the code cleaner then you should have separate methods for each role and use a switch case statement e.g.
private const string AdminRole = "ADMIN";
public async Task<PagedResponse<TodoItemBriefDto>> Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken)
{
switch (request.User.RoleId)
{
case AdminRole:
return await HandleAdmin();
default:
return await HandleOperator();
}
}
private async Task<PagedResponse<TodoItemBriefDto>> HandleAdmin()
{
return await _context.Set<TodoItemExample>();
}
private async Task<PagedResponse<TodoItemBriefDto>> HandleOperator()
{
return await _context.Set<TodoItemExample>()
.Where(x => x.UserId == request.User.Id));
}
英文:
What you have is fine but if by elegant, you mean less lines then you can move the condition into the where statement.
private const string AdminRole = "ADMIN";
public async Task<PagedResponse<TodoItemBriefDto>> Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken)
{
var userRole = request.User.RoleId;
return await _context.Set<TodoItemExample>()
.Where(x => userRole == AdminRole || x.UserId == request.User.Id));
}
If the user has the admin role then it won't filter the items that have the same user Id as the requesting user. This example assumes there are only two roles.
PS you should be using constant field members for known, unchanging strings as in the example above.
If you actually want to make the code cleaner then you should have separate methods for each role and use a switch case statement e.g.
private const string AdminRole = "ADMIN";
public async Task<PagedResponse<TodoItemBriefDto>> Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken)
{
switch (request.User.RoleId)
{
case AdminRole:
return await HandleAdmin();
default:
return await HandleOperator();
}
}
private async Task<PagedResponse<TodoItemBriefDto>> HandleAdmin()
{
return await _context.Set<TodoItemExample>();
}
private async Task<PagedResponse<TodoItemBriefDto>> HandleOperator()
{
return await _context.Set<TodoItemExample>()
.Where(x => x.UserId== request.User.Id));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论