zoukankan      html  css  js  c++  java
  • EF架构~真正被封装的排序方法,支持多列排序

    回到目录

    对于linq to sql 和linq to entity来说,当你把获取数据的方法封装了之后,总觉得还缺点什么,想了之后,应该是排序,但看了微软的orchard项目之后,觉得它的排序封装的并不好,而且还有多列排序的问题,所以,我自己又改进了一下,首先提出一个与分层无关的IOrderable接口的概念,它是为了让WEB,BLL,DATA层之间解耦的,其次增加了ThenAsc和ThenDesc让它们支持多列排序,orchard项目里,之前是使用参数来实现的,最多支持3列排序,而且不支持升降混排的情况,呵呵。

    看一个IOrderable接口

     /// <summary>
        /// 排序规范
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public interface IOrderable<T>
        {
            /// <summary>
            /// 递增
            /// </summary>
            /// <typeparam name="TKey"></typeparam>
            /// <param name="keySelector"></param>
            /// <returns></returns>
            IOrderable<T> Asc<TKey>(global::System.Linq.Expressions.Expression<Func<T, TKey>> keySelector);
            /// <summary>
            /// 然后递增
            /// </summary>
            /// <typeparam name="TKey1"></typeparam>
            /// <typeparam name="TKey2"></typeparam>
            /// <param name="keySelector1"></param>
            /// <returns></returns>
            IOrderable<T> ThenAsc<TKey>(Expression<Func<T, TKey>> keySelector);
            /// <summary>
            /// 递减
            /// </summary>
            /// <typeparam name="TKey"></typeparam>
            /// <param name="keySelector"></param>
            /// <returns></returns>
            IOrderable<T> Desc<TKey>(global::System.Linq.Expressions.Expression<Func<T, TKey>> keySelector);
            /// <summary>
            /// 然后递减
            /// </summary>
            /// <typeparam name="TKey"></typeparam>
            /// <param name="keySelector"></param>
            /// <returns></returns>
            IOrderable<T> ThenDesc<TKey>(Expression<Func<T, TKey>> keySelector);
            /// <summary>
            /// 排序后的结果集
            /// </summary>
            global::System.Linq.IQueryable<T> Queryable { get; }
        }

    OK,下面是为接口的一个实现,这个实现我是放在Data层的,因为它是与ORM架构有关的,可能你的linq与ado.net的排序实现是不同的,所以,不能放在entity层,我的习惯是,所有linq特有的都放在linq架构的Data层(如,IQueryable,这就是linq特有的,而list,IEnumerable等扩展应该放在entity层)

    namespace EntityFrameworks.Data.Core
    {
        /// <summary>
        /// Linq架构里对集合排序实现
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class Orderable<T> : IOrderable<T>
        {
            private IQueryable<T> _queryable;
    
            /// <summary>
            /// 排序后的结果集
            /// </summary>
            /// <param name="enumerable"></param>
            public Orderable(IQueryable<T> enumerable)
            {
                _queryable = enumerable;
            }
    
            /// <summary>
            /// 排序之后的结果集
            /// </summary>
            public IQueryable<T> Queryable
            {
                get { return _queryable; }
            }
            /// <summary>
            /// 递增
            /// </summary>
            /// <typeparam name="TKey"></typeparam>
            /// <param name="keySelector"></param>
            /// <returns></returns>
            public IOrderable<T> Asc<TKey>(Expression<Func<T, TKey>> keySelector)
            {
                _queryable = (_queryable as IOrderedQueryable<T>)
                    .OrderBy(keySelector);
                return this;
            }
            /// <summary>
            /// 然后递增
            /// </summary>
            /// <typeparam name="TKey"></typeparam>
            /// <param name="keySelector"></param>
            /// <returns></returns>
            public IOrderable<T> ThenAsc<TKey>(Expression<Func<T, TKey>> keySelector)
            {
                _queryable = (_queryable as IOrderedQueryable<T>)
                    .ThenBy(keySelector);
                return this;
            }
            /// <summary>
            /// 递减
            /// </summary>
            /// <typeparam name="TKey"></typeparam>
            /// <param name="keySelector"></param>
            /// <returns></returns>
            public IOrderable<T> Desc<TKey>(Expression<Func<T, TKey>> keySelector)
            {
                _queryable = _queryable
                    .OrderByDescending(keySelector);
                return this;
            }
            /// <summary>
            /// 然后递减
            /// </summary>
            /// <typeparam name="TKey"></typeparam>
            /// <param name="keySelector"></param>
            /// <returns></returns>
            public IOrderable<T> ThenDesc<TKey>(Expression<Func<T, TKey>> keySelector)
            {
                _queryable = (_queryable as IOrderedQueryable<T>)
                    .ThenByDescending(keySelector);
                return this;
            }
        }
    }

    而这个排序的方法,可以单独被BLL层使用,自己去组装它,也可以在Data层提供的GetModel()方法里直接使用,因为我的架构里已经有排序功能拟合到GetModel方法里了,看代码:

          public IQueryable<TEntity> GetModel(Action<IOrderable<TEntity>> orderBy)
            {
                var linq = new Orderable<TEntity>(GetModel());
                orderBy(linq);
                return linq.Queryable;
            }

    如果在其它层调用,可以自己去实例化Action<IOrderable<TEntity>>这个对象,如代码:

           backgroundEntities1 db = new backgroundEntities1();
                DbContextRepository<WebManageUsers> user = new DbContextRepository<WebManageUsers>(db);
                Action<IOrderable<WebManageUsers>> orderBy = query => query.Asc(j => j.DepartmentID)
                                                                           .ThenDesc(j => j.ManageUserID);
                user.GetModel(orderBy).ToList().ForEach(k =>
                {
                    Console.WriteLine("部门:" + k.DepartmentID + ",用户 :" + k.ManageUserID);
                });

     上面的代码是先对DepartmentID进行升序,再对ManageUserID进行降序,看一下结果如图:

     

    回到目录

  • 相关阅读:
    hdu 4521 小明系列问题——小明序列(线段树 or DP)
    hdu 1115 Lifting the Stone
    hdu 5476 Explore Track of Point(2015上海网络赛)
    Codeforces 527C Glass Carving
    hdu 4414 Finding crosses
    LA 5135 Mining Your Own Business
    uva 11324 The Largest Clique
    hdu 4288 Coder
    PowerShell随笔3 ---别名
    PowerShell随笔2---初始命令
  • 原文地址:https://www.cnblogs.com/lori/p/3505909.html
Copyright © 2011-2022 走看看