EF架(jia)構~linq to entity的隨機排序問題
對(dui)(dui)于從linq to sql遷移過來的開發者(zhe),對(dui)(dui)隨機(ji)排(pai)序不會感到陌生,直接為datacontext添加一個方法(fa)再配合(he)反射(she)就可以實(shi)現(xian)隨機(ji)排(pai)序了,代(dai)碼(ma)如下:
/// <summary> /// 數據(ju)上下(xia)文擴展(zhan) /// </summary> public partial class dbDataContext : IUnitOfWork { /// <summary> /// 隨(sui)機排序時使用這個函數(shu) /// </summary> /// <returns></returns> [Function(Name = "NewID", IsComposable = true)] public Guid NewID() { return ((Guid)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue)); } }
而(er)對(dui)于(yu)linq to entity的(de)(de)開發者們(men)就不能使(shi)用(yong)(yong)上(shang)面的(de)(de)方法(fa)了,因為dbcontext沒有(you)(you)(you)ExecuteMethodCall這個(ge)方法(fa),呵呵,只有(you)(you)(you)自己想轍了,事(shi)實上(shang),對(dui)于(yu)system.Data.Entity空間里有(you)(you)(you)一個(ge)EdmFunction的(de)(de)特性(xing),它(ta)(ta)與linq to sql里的(de)(de)Function特性(xing)類似,都是標識類為函(han)(han)數(shu),就是使(shi)用(yong)(yong)數(shu)據源的(de)(de)某個(ge)函(han)(han)數(shu),如Sqlserver的(de)(de)newid函(han)(han)數(shu),我們(men)可以把它(ta)(ta)思路整理一下,代碼就出(chu)來了,我們(men)像它(ta)(ta)種與領域無關的(de)(de)代碼放在core項目里,表(biao)示為公用(yong)(yong)代碼
/// <summary> /// sql函數的擴展類 /// </summary> public static class SqlFunctionExtensions { /// <summary> /// 在(zai)linq to entity中使用(yong)SqlServer.NEWID函(han)數(shu) /// </summary> [System.Data.Objects.DataClasses.EdmFunction("SqlServer", "NEWID")] public static Guid NewId() { return Guid.NewGuid(); } }
而為(wei)了使(shi)(shi)開發者(zhe)在使(shi)(shi)用(yong)(yong)上(shang)方法(fa),我們把NewId作(zuo)成IEnumerable接(jie)口的擴展方法(fa),這樣(yang)無(wu)論是(shi)(shi)IQueryable還(huan)是(shi)(shi)IList,List集合都可以直接(jie)使(shi)(shi)用(yong)(yong)它了,看代碼
/// <summary> /// sql函數的擴(kuo)展類 /// </summary> public static class SqlFunctionExtensions { #region 功能方法 /// <summary> /// 在linq to entity中使(shi)用SqlServer.NEWID函數 /// </summary> [System.Data.Objects.DataClasses.EdmFunction("SqlServer", "NEWID")] public static Guid NewId() { return Guid.NewGuid(); } #endregion #region 擴展方法 /// <summary> /// 隨(sui)機排序擴展方法 /// </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(); }
結果如下:
而(er)進行數據庫(ku)檢測的(de)結果(guo),出是令我們滿(man)意(yi)的(de),只取(qu)了5條數據

OK,到這(zhe)種(zhong)使用linq to entity(entity frameworks環境下)的隨機排(pai)序就介(jie)紹到這(zhe)里,謝謝閱讀!