EF Core – 查询根据角色不同而变化

huangapple go评论59阅读模式
英文:

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&lt;PagedResponse&lt;TodoItemBriefDto&gt;&gt; Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken)
{
      if(request.User.RoleId==&quot;OPERATOR&quot;)
      {
         return await _context.Set&lt;TodoItemExample&gt;()
            .Where(x =&gt; x.UserId== request.User.Id));
      }
     else 
     {
         return await _context.Set&lt;TodoItemExample&gt;();
     }
}

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 = &quot;ADMIN&quot;;
	
public async Task&lt;PagedResponse&lt;TodoItemBriefDto&gt;&gt; Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken)
{
	var userRole = request.User.RoleId;
	return await _context.Set&lt;TodoItemExample&gt;()
		.Where(x =&gt; 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 = &quot;ADMIN&quot;;

public async Task&lt;PagedResponse&lt;TodoItemBriefDto&gt;&gt; Handle(GetTodoItemsWithPaginationQuery request, CancellationToken cancellationToken)
{
	switch (request.User.RoleId)
	{
		case AdminRole:
			return await HandleAdmin();
		default:
			return await HandleOperator();
	}
}

private async Task&lt;PagedResponse&lt;TodoItemBriefDto&gt;&gt; HandleAdmin()
{
	return await _context.Set&lt;TodoItemExample&gt;();
}

private async Task&lt;PagedResponse&lt;TodoItemBriefDto&gt;&gt; HandleOperator()
{
	return await _context.Set&lt;TodoItemExample&gt;()
		.Where(x =&gt; x.UserId== request.User.Id));
}

huangapple
  • 本文由 发表于 2023年2月8日 23:15:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75387858.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定