2010-10-09 72 views
1
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; 
     } 
    } 
} 
+0

嗯,你可以肯定的因素'accessMA'和'accessRP'到它自己的方法,他们都呼吁,甚至到其自己的领域,因为它还是要用延迟执行您在创建设置。 – 2010-10-09 20:31:22

+0

@Kirk Woll:访问MA的查询在IsAccessible和GetAccessible中不一样(对于accessRP也一样)。 – 2010-10-09 21:38:26

回答

0

一提的是,这是个人意见,我们都在这里他们有云:

  1. 在查询内沟通使用lambda表达式。选择一种风格,并使用它的家伙。
  2. 摆脱where子句中的&符号。你可以用另一行从where开始获得相同的结果。
  3. 不要害怕查询另一个查询。如果它更容易理解,没有理由不这样做。编译器会将它们合并为一个查询。
  4. 许多人会指出,静态方法通常指向代码味道。为什么你需要静态和实例方法?也许班上的一些清晰度是有条理的。
0

是不是很简单:

public static IEnumerable<MembershipModule> GetAccesible() 
{ 
    // Skip unnecessary querying 
    if(!MembershipUser.Connected) 
     return LinqUtil.Context.MembershipModules.Where(m => m.Enabled && m.OfflineAccess).ToList(); 

    // Accessible modules 
    var modules = 
     from m in LinqUtil.Context.MembershipModules 
     where m.IsAccessible() 
     select m; 

    return modules.ToList(); 
}