代码之家  ›  专栏  ›  技术社区  ›  bevacqua

简化过于复杂的LINQ查询

  •  1
  • bevacqua  · 技术社区  · 15 年前
    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() 函数这不会发生。我可以补充一下 到查询,但它在实例中 IsAccessible()

    作为记录,以下是成员资格操作:

    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;
            }
        }
    }
    
    2 回复  |  直到 15 年前
        1
  •  0
  •   Kirk    15 年前

    提到这是个人观点,我们都有这样的看法:

    1. 不要在查询中使用lambda表达式。选一种风格然后用它伙计。
    2. 去掉where子句中的与号。你可以用另一条线从哪里开始得到同样的结果。
    3. 别害怕再问一个问题。如果能让人更容易理解,就没有理由不去做。编译器将把它们组合成一个查询。
        2
  •  0
  •   GôTô    15 年前

    不是很简单吗:

    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();
    }