简化过于复杂的 LINQ 查询 - 查询
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);
}
}
这目前有效,但出于某种原因,我忍不住认为代码看起来很丑(特别是两个非常相似的静态和实例函数,它们让我获得可访问的页面
关于如何重构它以使其看起来更有吸引力有什么想法吗?
额外问题:
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;
}
}
}
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);
}
}
This currently works, but for some reason I can't help but to think the code looks ugly (particularly the two very similar static and instance functions that get me the accessible pages
Any thoughts on how to refactor this to look more appealing?
Bonus question:
Guid accessGuid = MembershipAction.AccessGuid;
Without using that line, and just calling MembershipAction.AccessGuid
in my query, I get an error telling me something obscure:
Class member
MembershipAction.AccessGuid is
unmapped.
The tricky parts comes here: in the static GetAccessible()
function this doesn't happen. I can just add MembershipAction.AccessGuid
to the query, but it's in the instance IsAccessible()
function that I get this problem.
For the record, here's 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;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
需要指出的是,这是个人观点,我们在这里都有这样的观点:
Mentioning that this is personal opinion and we all have them here goes:
是不是很简单:
Isn't it simply: