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