1

我有以下 ActionFilter 类来实现我的自定义授权系统:-

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class CheckUserPermissionsAttribute : ActionFilterAttribute
    {
        Repository repository = new Repository();
        public string Model { get; set; }
        public string Action { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
string ADusername = filterContext.HttpContext.User.Identity.Name.Substring(filterContext.HttpContext.User.Identity.Name.IndexOf("\\") + 1);
            if (!repository.can(ADusername,Model,Action)) 
            {
                filterContext.Result = new HttpUnauthorizedResult("You cannot access this page");

            }

            base.OnActionExecuting(filterContext);
        }
    }

上面的类将调用以下存储库方法:-

   public bool can(string user, string Model, string Action)
            {
                bool result;
                bool result2;
    int size =tms.PermisionLevels.Where(a5 => a5.Name == Action).SingleOrDefault().PermisionSize;
    var securityrole = tms.SecurityroleTypePermisions.Where(a => a.PermisionLevel.PermisionSize >= size && a.TechnologyType.Name == Model).Select(a => a.SecurityRole).Include(w=>w.Groups).Include(w2=>w2.SecurityRoleUsers).ToList();

    foreach (var item in securityrole)
                        {
    result = item.SecurityRoleUsers.Any(a => a.UserName.ToLower() == user.ToLower());
    var no = item.Groups.Select(a=>a.TMSUserGroups.Where(a2=>a2.UserName.ToLower() == user.ToLower()));
    result2 = no.Count() == 1;
    if (result || result2) {
        return true;
    }}
    return false;
    }

但是在我的存储库方法中,我正在执行以下操作:-

  1. 执行 .tolist() 时查询数据库并包括所有组和 SecurityRoleUsers

  2. 然后根据 foreach 循环过滤服务器内返回的记录。

但这会导致以下缺点:-

  1. 如果我有很多组和 SecurityRoleUsers,那么我将从数据库中获取它们,然后在服务器上过滤结果。

  2. 并且由于每当调用动作方法时都会执行此代码,因为它是控制器类请求时的安全属性。所以这可能不是很有效。

所以我的问题是我是否可以将存储库方法中的所有查询加入到单个查询中,并在数据库上完成所有工作,然后向服务器返回 true 或 false?相关表格如下所示:-

在此处输入图像描述

4

3 回答 3

1

理想情况下删除此 foreach。尝试使用 Linq to Sql。你应该更舒服,因为它类似于 SQL。

这个链接有几个例子。 http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

攻击者

胡里奥·斯派德

wessolucoes.com.br

于 2013-10-30T19:40:41.507 回答
-1

您需要注意延迟加载。如果使用不正确,它会对数据库中的每个对象进行查询,尤其是在你的 foreach 中。有了这个已经有了很好的改进。

看看这篇文章。我想它也会对你有所帮助。

http://www.sql-server-performance.com/2012/entity-framework-performance-optimization/

攻击者

胡里奥·斯派德

wessolucoes.com.br

于 2013-10-29T01:55:54.653 回答
-1

使用 linq。理想情况下,在获得 size 值后,您应该只有一行代码。例如

int size =tms.PermisionLevels.Where(a5 => a5.Name == Action).SingleOrDefault().PermisionSize;

var result = //One line of code to determine user authenticity

return result;

我认为您应该以易于执行连接查询的方式设计数据库。因此,您不必执行多个选择。

尝试代码优先的 EF,它非常容易链接表。

于 2013-10-29T01:47:52.393 回答