在上一篇介紹完了如何動態產生Linq條件之後,在這一篇,將會透過Reflection和Dynamic Linq Query來讓Service層,能夠在不做任何事情的情況下,自動對資料做過濾,並且轉成對應的ViewModel配上分頁。
Service層的處理
在處理搜索的部份,Service層將會需要:
- 透過Reflection取得要搜索的欄位 - 這邊要記得是不要base的欄位(不要那些例如目前在第幾頁,和一頁幾筆的那種)
- 依照Reflection的欄位和Dynamic LInq Query組成搜索條件
- 做搜索並且用Automapper把Entity 對應到ViewModel搭配分頁
Service處理搜索的方法
首先,之前的那個GenericService
將會多一個方法叫做ProcessIndexViewModel
基本上ProcessIndexViewModel
會接受一個之前定義過的SearchViewModelBase
的形態,同時假設搜索的內容需要做到Include的話,可以設定。
再來就詳細看一下實際做搜索的邏輯。
ApplySearchForm
會在呼叫兩個方法,一個是下搜索條件,一個是做實際的搜索的呼叫AutoMapper,先來看一下實際的搜索。 Reflection取得欄位值和組成搜索條件
這邊注意到核心是取得properties
的部分,只需要後來繼承的欄位,和注意不要取得複寫的欄位,例如OrderByColumnName
。之後,就是用Dynamic Linq Query來組裝搜索條件。
執行完了DynamicWhere
,就有了搜索的條件,接下來就是執行搜索條件並且轉成對應的ViewModel和分頁。
做搜索和用AutoMapper對應
可以看到,先依照欄位做排序(這邊需要注意到OrderBy
也是Dynamic Linq Query的方法),然後在把資料轉型把結果放到Result裡面。
Controller呼叫搜索
在前面呼叫就變得比較簡單:
Service是和之前一樣注入進來的。這邊把Index ViewModel作為方法參數是有兩個用意:
- 如果要做搜索或者按下下一頁的時候,會直接post back到這一邊,因此要接住才可以。
- 當第一次get的時候,為了邏輯一致,因此還是要呼叫
ProcessIndexViewModel
,但是如果Index ViewModel沒有被實例化,會造成裡面Property是null 導致出錯。
結語
透過這一篇,可以讓框架幫我們針對一般的欄位和條件自動做搜索和分頁,不過這一篇沒有介紹在View上面如何使用。
在下一篇,將會介紹如何透過template讓產生的搜索欄位在不同功能看起來一致,並且一些helper來幫助產生url。