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進行降序,看一下結果如圖:

 

回到目錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM