對於從linq to sql遷移過來的開發者,對隨機排序不會感到陌生,直接為datacontext添加一個方法再配合反射就可以實現隨機排序了,代碼如下:
/// <summary> /// 數據上下文擴展 /// </summary> public partial class dbDataContext : IUnitOfWork { /// <summary> /// 隨機排序時使用這個函數 /// </summary> /// <returns></returns> [Function(Name = "NewID", IsComposable = true)] public Guid NewID() { return ((Guid)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue)); } }
而對於linq to entity的開發者們就不能使用上面的方法了,因為dbcontext沒有ExecuteMethodCall這個方法,呵呵,只有自己想轍了,事實上,對於system.Data.Entity空間里有一個EdmFunction的特性,它與linq to sql里的Function特性類似,都是標識類為函數,就是使用數據源的某個函數,如Sqlserver的newid函數,我們可以把它思路整理一下,代碼就出來了,我們像它種與領域無關的代碼放在core項目里,表示為公用代碼
/// <summary> /// sql函數的擴展類 /// </summary> public static class SqlFunctionExtensions { /// <summary> /// 在linq to entity中使用SqlServer.NEWID函數 /// </summary> [System.Data.Objects.DataClasses.EdmFunction("SqlServer", "NEWID")] public static Guid NewId() { return Guid.NewGuid(); } }
而為了使開發者在使用上方法,我們把NewId作成IEnumerable接口的擴展方法,這樣無論是IQueryable還是IList,List集合都可以直接使用它了,看代碼
/// <summary> /// sql函數的擴展類 /// </summary> public static class SqlFunctionExtensions { #region 功能方法 /// <summary> /// 在linq to entity中使用SqlServer.NEWID函數 /// </summary> [System.Data.Objects.DataClasses.EdmFunction("SqlServer", "NEWID")] public static Guid NewId() { return Guid.NewGuid(); } #endregion #region 擴展方法 /// <summary> /// 隨機排序擴展方法 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <returns></returns> public static IQueryable<T> OrderByNewId<T>(this IEnumerable<T> source) { return source.AsQueryable().OrderBy(d => NewId()); } #endregion }
而使用了IEnumerable的集合擴展后,它是否還有延時加載的特性,通過我們的檢測,答案是肯定的,它是延時的,下面是我們的例子
public ActionResult Index() { var list = irepository.GetEntities(); ViewBag.List = list.OrderByNewId().Take(5).ToList();//只取5條 return View(); }
結果如下:
而進行數據庫檢測的結果,出是令我們滿意的,只取了5條數據
OK,到這種使用linq to entity(entity frameworks環境下)的隨機排序就介紹到這里,謝謝閱讀!