(转)动态Entity Framework查询:Dynamic Query 介绍
原文地址:http://www.cnblogs.com/yinzixin/archive/2012/11/30/entity-framework-dynamic-query.html
Dynamic Query是一個(gè)支持動(dòng)態(tài)Entity Framework查詢的庫。它的設(shè)計(jì)初衷是為了減少在管理系統(tǒng)中大量出現(xiàn)的對(duì)一個(gè)數(shù)據(jù)集進(jìn)行查找、排序、分頁的這類場景的開發(fā)工作量,其設(shè)計(jì)思想是”markup is code ”。通過在View上編寫具有語義信息的標(biāo)簽,來實(shí)現(xiàn)這類常見的功能需求,而不再需要額外的代碼。它不是一個(gè)完整的ORM,是基于Entity Framework的,因此開發(fā)者仍然可以利用Entity Framework提供的大量特性,和現(xiàn)有的EF項(xiàng)目保持兼容。
Dynamic Query分為兩個(gè)部分,其中之一是一個(gè)查詢接口,這是一個(gè)IQueryable<T>的擴(kuò)展方法:
public static IQueryable<T> Query<T>(this IQueryable<T> data, QueryDescriptor descriptor)?
其中QueryDescriptor是一個(gè)簡單的類,包含了一個(gè)查詢的必要信息,例如,篩選條件,排序信息,分頁信息等。
例如:
QueryDescriptor descriptor = new QueryDescriptor{OrderBy = new OrderByClause { Key = "Price", Order = OrderSequence.ASC },PageSize = 3,PageIndex = 1,Conditions=new QueryCondition[] {new QueryCondition { Key = "Name",Value = "Rice", Operator = QueryOperator.CONTAINS }}};int pageCount;var res=ctx.Products.Query(descriptor, out pageCount);這相當(dāng)于執(zhí)行了查詢:
select * from Product where [Name] like N'%Rice%' order by Price asc并且對(duì)結(jié)果進(jìn)行分頁,每頁3條數(shù)據(jù),返回第一頁。注意,這里返回的結(jié)果是IQueryable<T>,這實(shí)際上是一個(gè)Entity Framework的查詢,在沒有序列化之前,并沒有對(duì)數(shù)據(jù)庫進(jìn)行操作,分頁也是發(fā)生在服務(wù)器端的,這對(duì)于大數(shù)據(jù)來說能夠極大的減少網(wǎng)絡(luò)傳輸和內(nèi)存使用量。 當(dāng)然,手動(dòng)構(gòu)造這樣一個(gè)QueryDescriptor也是一件非常無趣的事情,為此Dynamic Query還為asp.net MVC 實(shí)現(xiàn)了一系列的helper方法和一個(gè)model binder,來自動(dòng)生成QueryDescriptor。我們最終的目標(biāo)是獲得頁面提交的數(shù)據(jù),自動(dòng)生成QueryDescriptor對(duì)象。為此,需要注冊(cè)一下一個(gè)自定義的binder,只需要在Global.asax的Application_Start中添加一行代碼:
ModelBinders.Binders.Add(typeof(QueryDescriptor), new QueryDescriptorBinder());?
假如我們有如下的EF模型:
我們來實(shí)現(xiàn)一個(gè)列表,對(duì)Product的Name進(jìn)行篩選。這時(shí)候,可以使用QueryTextbox擴(kuò)展方法來生成查詢字段,View的代碼如下:
<div class="container"> <form class=".form-search">@Html.QueryTextbox("Name", "Product Name", QueryOperator.CONTAINS) <input type="submit" value="Search" class="btn"/></form> </div> <div class="row"><div class="span12 offset2 "><table class="table table-striped"><thead><tr><td>ID</td><td>Category</td><td>Name</td><td>Price</td><td>Description</td></tr></thead><tbody>@foreach (var p in @Model){<tr><td>@p.Id</td><td>@p.Category.Name</td><td>@p.Name</td><td>@p.Price</td><td>@p.Description</td></tr>}</tbody></table></div> </div>?
上半部分是一個(gè)form,里面有一個(gè)QueryTextBox,下半部分就是一個(gè)列表,非常簡單??磳?duì)應(yīng)的Action:
public ActionResult Index(QueryDescriptor descriptor){ShopContainer ctx = new ShopContainer();var result = ctx.Products.Query(descriptor);return View("Product",result);}由于Model Binder的存在,Action會(huì)從頁面獲得QueryDescriptor的信息。這樣一個(gè)篩選頁面就做好了。如果客戶說,我還要增加對(duì)種類名稱和價(jià)格范圍的篩選,那需要改什么地方?只需要在View的form中添加幾個(gè)QueryTextbox就可以了。
<form class=".form-search">@Html.QueryTextbox("Name", "Product Name", QueryOperator.CONTAINS)@Html.QueryTextbox("Category.Name", "Product Category", QueryOperator.CONTAINS)@Html.QueryTextbox("Price.1", "Price Between", QueryOperator.GREATEROREQUAL,"decimal")@Html.QueryTextbox("Price.2", "", QueryOperator.LESSOREQUAL,"decimal")<input type="submit" value="Search" class="btn"/></form>注意,Price出現(xiàn)了兩次,需要加上數(shù)字后綴區(qū)分一下就可以,如果不是string類型,加上類型的說明,這樣就OK。Action方法是不需要有任何改動(dòng)的。
如果客戶說這個(gè)要分頁怎么辦? 分頁需要稍微多些兩行代碼,但是也只需要2分鐘就足夠,先看Action方法:
public ActionResult Product(QueryDescriptor descriptor){descriptor.PageSize = 5;descriptor.OrderBy = new OrderByClause { Key = "Id", Order = OrderSequence.ASC };ShopContainer ctx = new ShopContainer();int pageCount;var result = ctx.Products.Query(descriptor, out pageCount);Pager pager = new Pager(pageCount, descriptor);ViewBag.Pager = pager;return View("Index",result);}首先指定一頁顯示的數(shù)量,因?yàn)橐猪?#xff0c;必須要有排序信息,這里是根據(jù)Id,升序排列。接下來還是調(diào)用Query方法獲得數(shù)據(jù),注意,這里是Query的一個(gè)重載的方法,能夠返回總共有多少頁,這一般是分頁控件需要的信息。接下來實(shí)例化一個(gè)Pager對(duì)象,這個(gè)Pager是一個(gè)分頁器,包含在Dynamic Query中,如果你想用其他第三方的分頁器,也是可以的。Pager需要的額外信息就是總頁數(shù),把這個(gè)Pager放到ViewBag上面,然后Action的工作就完成了。View上面也不想要任何改變,如果你想加上分頁鏈接的話,只需要一行代碼:
@Html.QueryPager((Pager)ViewBag.Pager);看看效果:
?
項(xiàng)目主頁和源代碼在:http://dynamicquery.codeplex.com/? 上面有一個(gè)樣例程序,更多文檔在完善中。
這個(gè)項(xiàng)目才開始沒多久,還有很多細(xì)節(jié)需要完善,主要是樣式、支持更多的控件,比如checkbox,dropdownlist等。以后慢慢補(bǔ)充。
轉(zhuǎn)載于:https://www.cnblogs.com/fcsh820/archive/2012/12/06/2804595.html
總結(jié)
以上是生活随笔為你收集整理的(转)动态Entity Framework查询:Dynamic Query 介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SDUTOJ2828_字典树
- 下一篇: CI框架--加载静态内容