在实体框架中按权限筛选行的最佳方法

本文关键字:最佳 方法 筛选 权限 实体 框架 | 更新日期: 2023-09-27 18:27:46

在我的项目中,我有一些帖子,如NewsArticleAnnouncement和...

每个帖子都有权限,例如 Id 的新闻帖子1只有管理员用户可以这样做......

如果登录,我应该按用户角色显示帖子。

为此,我尝试某种方式:

方式1:我添加了一个扩展方法来过滤新闻,文章,...喜欢这个

public static class EfExtensionMethods
{
   public  IEnumerable<News> Filter( IDbSet<News> dbset) 
   {
      return (dbset.Where(...));
   }
}

方式2:我在服务层中添加了一个过滤器行的方法,如下所示:

public void FilterNews(IEnumerable<News> newsList)
{
   var roles = _currentUserService.GetCurrentUserRoles();
   if (roles.Count == 0)
   {
      newsList = newsList.Where(...).ToList();
   }
   else
   {
      newsList = newsList.Where(...).ToList();
   }
}

到处我只需要将新闻列表传递给此方法即可过滤.女巫一号被困住了?

有什么最好的方法吗?我想要一种可重用且不为每个类复制的方法

在实体框架中按权限筛选行的最佳方法

你应该用静态Expressions创建一个静态类,你可以在查询中使用那些,然后它过滤数据库(现在你从数据库中获取所有行并扔掉你不需要的那些,这是一种浪费(:

partial class News
{
    public static class Q
    {
        public static Expression<Func<News,bool>> HasPermission(int permissionID)
        {
            return expr => expr.PermissionID == permissionID
        }
     }
 }

然后,您可以执行如下查询,例如:

db.News.Where(News.Q.HasPermission(1)).ToList();

您将仅从权限等于"1"的News表中获取行。我真的不知道您的权限是如何存储的,但我认为您明白:)

编辑:对于泛型,我认为最简单的方法是让你的模型继承自 Permissionbase 类或其他东西:

public abstract class PermissionBase
{
   public int PermissionID {get; set;}
}
public static class QueryExtensions
{
   public static Expression<Func<T,bool>> HasPermission<T>(int permissionID) where T: PermissionBase
   {
       return expr => expr.PermissionID == permissionID
   }
}

如果没有基类,通过在运行中构建Expression也应该成为可能:

public static Expression<Func<T, bool>> HasPermission<T>(int PermissionID) where T : class
{
   ParameterExpression pe = Expression.Parameter(typeof(T), "p");
   System.Reflection.PropertyInfo pi = typeof(T).GetProperty("PermissionID");
   MemberExpression me = Expression.MakeMemberAccess(pe, pi);
   ConstantExpression ce = Expression.Constant(PermissionID);
   BinaryExpression be = Expression.Equal(me, ce);
   return Expression.Lambda<Func<T, bool>>(be, pe);
}

只需确保属性名称在所有模型中都是正确的,或者您可以使用字符串将属性名称传递给方法。

我假设您谈论的是行级安全性。这是一项相当复杂的任务。有几种方法可以做到这一点。

对于 MSSQL,请尝试查看有关 RLS 的 MSDN 安全博客