public partial class MembershipModule : BaseEntity<MembershipModule>
{
/// <summary>
/// Returns wheter a module is accessible
/// </summary>
public static bool IsAccessible(MembershipModule module)
{
// In absence of a module, no security applies to the page
if(module == null)
return true;
return module.IsAccessible();
}
/// <summary>
/// Returns whether the module is accessible
/// </summary>
/// <returns></returns>
public bool IsAccessible()
{
// Skip unnecessary querying
if(!MembershipUser.Connected)
return this.Enabled && this.OfflineAccess;
Guid accessGuid = MembershipAction.AccessGuid;
// ModuleActions for this MembershipModule and the Access Action
IQueryable<MembershipModuleAction> accessMA =
from ma in LinqUtil.Context.MembershipModuleActions
where ma.ModuleId.Equals(this.Id) && ma.ActionId.Equals(accessGuid)
select ma;
// RolePrivileges that grant access on this MembershipModule for the Current MembershipUser
IQueryable<bool> accessRP =
from rp in LinqUtil.Context.MembershipRolePrivileges
where accessMA.Contains(rp.MembershipModuleAction)
select rp.MembershipRole.MembershipUsers.Contains(MembershipUser.Current);
return this.Enabled && (this.OfflineAccess || accessRP.ToList().FirstOrDefault());
}
/// <summary>
/// Returns all accessible modules that can be accessed by the logged user
/// </summary>
/// <returns></returns>
public static IEnumerable<MembershipModule> GetAccesible()
{
// Skip unnecessary querying
if(!MembershipUser.Connected)
return LinqUtil.Context.MembershipModules.Where(m => m.Enabled && m.OfflineAccess).ToList();
Guid accessGuid = MembershipAction.AccessGuid;
// ModuleActions for any MembershipModule with the Access Action
IQueryable<MembershipModuleAction> accessMA =
from ma in LinqUtil.Context.MembershipModuleActions
where LinqUtil.Context.MembershipModules.Any(m => m.Enabled && m.Id.Equals(ma.ModuleId)) && ma.ActionId.Equals(accessGuid)
select ma;
// RolePrivileges that grant access on those MembershipModule for the Current MembershipUser
IQueryable<MembershipRolePrivilege> accessRP =
from rp in LinqUtil.Context.MembershipRolePrivileges
where accessMA.Any(ma => rp.MembershipModuleAction.Id.Equals(ma.Id)) && rp.MembershipRole.MembershipUsers.Any(u => u.Id.Equals(MembershipUser.Current.Id))
select rp;
// Accessible modules
var modules =
from m in LinqUtil.Context.MembershipModules
where accessMA.Any(ma => ma.MembershipModule.Id.Equals(m.Id)) && accessRP.Any(rp => rp.MembershipModuleAction.ModuleId.Equals(m.Id))
select m;
return modules.ToList();
}
/// <summary>
/// Menu Items that can be displayed on the current web page
/// </summary>
public static IEnumerable<MembershipModule> GetMenuItems(string uriPrefix)
{
IEnumerable<MembershipModule> list = GetAccesible();
return list.Where(m => m.UriPrefix.Equals(uriPrefix) && m.MenuItem).OrderBy(m => m.Position);
}
}
这个当前工作,但由于某些原因,我不禁联想到的代码看起来丑陋(尤其是两个非常相似的静态和实例函数,让我的访问页面简化过于复杂的LINQ查询 - 查询
如何重构这个有什么想法看起来更吸引人
奖金的问题:
Guid accessGuid = MembershipAction.AccessGuid;
不使用该行,而只是调用我的查询MembershipAction.AccessGuid
,我得到一个错误,告诉我一些晦涩:
类成员 MembershipAction.AccessGuid是 未映射。
棘手的部分来了:在静态GetAccessible()
函数这不会发生。我可以将MembershipAction.AccessGuid
添加到查询中,但它在实例IsAccessible()
函数中出现此问题。
为了记录在案,这里的MembershipAction:
public partial class MembershipAction : BaseEntity<MembershipAction>
{
public const string AccessPrivilege = "Access";
private static Guid accessGuid = Guid.Empty;
public static Guid AccessGuid
{
get
{
if(accessGuid == Guid.Empty)
{
IQueryable<Guid> query = from a in LinqUtil.Context.MembershipActions
where a.Name.Equals(AccessPrivilege)
select a.Id;
accessGuid = query.ToList().FirstOrDefault();
}
return accessGuid;
}
}
}
嗯,你可以肯定的因素'accessMA'和'accessRP'到它自己的方法,他们都呼吁,甚至到其自己的领域,因为它还是要用延迟执行您在创建设置。 – 2010-10-09 20:31:22
@Kirk Woll:访问MA的查询在IsAccessible和GetAccessible中不一样(对于accessRP也一样)。 – 2010-10-09 21:38:26