2014-10-26 23 views
0

我有一個簡單Person View Model如何將一個簡單的viewmodel轉換爲Func <T,bool>謂詞?

public class PersonViewModel 
{ 
    public int ID {get;set;} 
    public String FirstName {get;set;} 
    public String LastName {get;set;} 
} 

視圖有三個字段

form

我有我的PersonService這個功能,使用了EF6的datacontext這被注入。

public IQueryable<Person> Search(Expression<Func<Person,bool>> predicate) 
     { 
      return dataContext.GetSet<Person>().Where(predicate); 
     } 

現在我的MVC控制器實際上有PersonViewModel class

[HttpPost] 
public ActionResult Search(PeopleSearchViewModel model) 
{ 
     if (ModelState.IsValid) 
      { 
       var listOfPersons= PersonService.Search(
        //map viewmodel to model and search here) 

       //return the list and render a view etc...not important 
      } 
     } 

工作那麼我想知道是它是否是一個好主意,如果我能以某種方式把PersonViewModel,創建一個Func<Person,bool>謂詞,並將其傳遞到PersonService進行搜索,而不是使用automapper將我的視圖模型映射到域模型?

感謝

+0

它不會正常工作,因爲你發送'Func <>'到'Where'方法,然後所有的過濾將在.Net端完成,整個表將從DB加載,這是不好的。它應該是'Expression >' – 2014-10-26 21:47:30

+0

對不起,我錯過了,我已經更新了代碼 - 儘管我不確定這是否是你的意思。 – 2014-10-26 21:52:10

+0

是的,我的意思是。嗯,'搜索'方法用於過濾。它不需要'Person'類的實例,那麼你的問題是什麼?你想使用'PersonSearchViewModel'進行'搜索'過濾? – 2014-10-26 21:54:23

回答

1

首先,你逝去的類型Func鍵作謂語,在返回一個IQueryable的功能。實際上,你應該傳遞一個Expression<Func<Person, bool>>,以便任何生成查詢的實際上都可以將該函數視爲表達式樹並從中生成SQL或其他東西。如果你不這樣做,你的查詢生成器可能會最終加載你的整個表並手動迭代(看到這發生在實體框架一次)。

到您的答案:我會做一個功能在您PeopleSearchViewModel像這樣:

public Expression<Func<Person, bool>> ToExpression() 
{ 
    //this can be whatever your search query needs to be... I just did this quick and dirty 
    return p => p.FirstName == this.FirstName || p.LastName == this.LastName || p.ID == this.ID; 
} 

然後,只需通過調用model.ToExpression()您的搜索功能的結果。

+0

+1這看起來完全像我想的那樣,但正如我在問題中提到的那樣,我忽略了這個明顯的缺點? – 2014-10-26 21:57:57

+0

如果您的搜索模型或人員模型發生更改,它確實需要手動修改,但是您必須處理該問題,除非最終使用某種映射器庫。但是這應該是唯一的主要問題......我始終都在使用這種模式 – 2014-10-26 21:59:38

+0

謝謝......嘗試創建此ToExpression函數的通用版本會不合理嗎?或者我必須爲每個視圖模型創建一個? – 2014-10-26 22:29:22

相關問題