我有以下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;
}
但是在我的存储库方法中,我正在执行以下操作: -
查询数据库并包含所有组&执行.tolist()
然后根据foreach循环过滤服务器中返回的记录。
但这会导致以下缺点: -
如果我有很多Group和SecurityRoleUsers,那么我将从数据库中获取所有这些,然后在服务器上过滤结果。
因为只要调用一个action方法就会执行这段代码,因为它是控制器类求助时的一个安全属性。所以这可能效率不高。
所以我的问题是我是否可以将存储库方法中的所有查询加入到单个查询中,并在数据库上完成所有工作并只返回true或false到服务器? 相关表格如下: -
答案 0 :(得分:1)
理想情况下删除此foreach。 尝试使用Linq to Sql。 你应该更舒服,因为它类似于SQL。
此链接有几个例子。 http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
ATT
Julio Spader
答案 1 :(得分:-1)
使用linq。 理想情况下,在获得大小值后,您应该只有一行代码。 e.g。
int size =tms.PermisionLevels.Where(a5 => a5.Name == Action).SingleOrDefault().PermisionSize;
var result = //One line of code to determine user authenticity
return result;
我认为您应该以连接查询很容易的方式设计数据库。因此,您不必执行多个选择。
尝试代码优先EF,它可以非常轻松地链接表格。
答案 2 :(得分:-1)
您需要注意延迟加载。如果使用不当,它将向数据库中的每个对象分段进行查询,尤其是在您的foreach中。已经有了很好的改进。
看看这篇文章。我认为它也会对你有所帮助。
http://www.sql-server-performance.com/2012/entity-framework-performance-optimization/
ATT
Julio Spader