ASP.NET MVC & EF 構建智能查詢 二、模型的設計與ModelBinder

來源:互聯網
上載者:User

在第一篇中,我講解了我們要做智能查詢的原因,以及基本的解決方案設計。從這篇開始我們開始講解它的實現過程。

其實在寫這一系列文章之初,我其實是想由底至上去講解,但是我又整理了一遍代碼才發現,其實如果不瞭解最表面的東西,也是不太好深入的。

所以我們的第二篇文章就來講一下我們這個智能查詢方塊架中最淺,但也是使用最頻繁的部分,也就是Model。

首先我們的Entity  或者說資料庫的結構如下

另外如下面代碼,我們有一個用於傳遞name=value對,及查詢謂詞的model

   1: public ActionResult Index(QueryModel model)

   2: {

   3:     using(var db=new DbEntities())

   4:     {

   5:         var list = db.Users.Where(model).ToList();

   6:         return View(list);

   7:     }

   8: }

我命名之為QueryModel。它由Action的參數傳入,再傳入EF的Where擴充方法,它是構建Lambda運算式的原型,上面是我們的一個通用的查詢Action的代碼。

 

而QueryModel的代碼為

QueryModel的唯一一個屬性Items,是一個ConditionItem的集合,它裡面存著所有的查詢條件。

而ConditionItem裡面的屬性

  1. Field表示要查詢的目標屬性的名稱,我們的設定它是支援子屬性查詢的,例如 “Profile.MyUser.Id”
  2. Method則是當前使用的謂詞,它是QueryMethod的一個枚舉值
  3. OrGroup是一個字串,是一個OrGroup的多個運算式將會以Or操作符進行關聯,然後再And
  4. Prefix是一個分類的首碼,我們假定一個Action可能處理多個查詢條件組的時候為了分開這些查詢條件而加的屬性
  5. Value則是這個表達試的值

 

而我們在頁面上類似

   1: <form action="" method="post">

   2: 姓名:<input id="Name" name="[Like]Name" type="text" value="" />   

   3: Email:<input id="Email" name="[Equal]Email" type="text" value="" /><br />

   4: Id: <input id="Id" name="[Equal]Id" type="text" value="" />

   5: 生日: <input id="Birthday" name="[Equal]Birthday" type="text" value="" /><br />

   6: <input type="submit" value="查詢" />

   7: </form>

這樣的表單,我們提交到伺服器端,我們要進行ASP.NET MVC 中IModelBinder的轉換,要將querystring 或 postdata中的KeyValuePair轉換為我們的ConditionItem。

當然,我們除了謂詞Method之外,還有Prefix以及OrGroup要從用戶端提交過來所以我們就要制定一個規則

我們約定

  1. 中括弧[]中的為查詢謂詞
  2. 小括弧()中的為首碼Prefix
  3. 大括弧{}中的為OrGroup

我們可以通過以下IModelBinder的實現將Request.QueryString或Request.Form中的值轉換到QueryModel中:

   1: public class SearchModelBinder : IModelBinder

   2:    {

   3:        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 

   4:        {

   5:            var model = (QueryModel)(bindingContext.Model ?? new QueryModel());

   6:            var dict = controllerContext.HttpContext.Request.Params;

   7:            var keys = dict.AllKeys.Where(c => c.StartsWith("["));//我們認為只有[開頭的為需要處理的

   8:            if (keys.Count() != 0)

   9:            {

  10:                foreach (var key in keys)

  11:                {

  12:                    if (!key.StartsWith("[")) continue;

  13:                    var val = dict[key];

  14:                    //處理無值的情況

  15:                    if (string.IsNullOrEmpty(val)) continue;

  16:                    AddSearchItem(model, key, val);

  17:                }

  18:            }

  19:            return model; 

  20:        }

  21:  

  22:        /// <summary>

  23:        /// 將一組key=value添加入QueryModel.Items

  24:        /// </summary>

  25:        /// <param name="model">QueryModel</param>

  26:        /// <param name="key">當前項的HtmlName</param>

  27:        /// <param name="val">當前項的值</param>

  28:        public static void AddSearchItem(QueryModel model, string key, string val)

  29:        {

  30:            string field = "", prefix = "", orGroup = "", method = "";

  31:            var keywords = key.Split(']', ')', '}');

  32:            //將Html中的name分割為我們想要的幾個部分

  33:            foreach (var keyword in keywords)

  34:            {

  35:                if (Char.IsLetterOrDigit(keyword[0])) field = keyword;

  36:                var last = keyword.Substring(1);

  37:                if (keyword[0] == '(') prefix = last;

  38:                if (keyword[0] == '[') method = last;

  39:                if (keyword[0] == '{') orGroup = last;       

  40:            }

  41:            if (string.IsNullOrEmpty(method)) return;

  42:            if (!string.IsNullOrEmpty(field))

  43:            {

  44:                var item = new ConditionItem

  45:                               {

  46:                                   Field = field,

  47:                                   Value = val.Trim(),

  48:                                   Prefix = prefix,

  49:                                   OrGroup = orGroup,

  50:                                   Method = (QueryMethod) Enum.Parse(typeof (QueryMethod), method)

  51:                               };

  52:                model.Items.Add(item);

  53:            }

  54:        }

  55:    }

 

當然我們還要在Global.asax中添加

   1: ModelBinders.Binders.Add(typeof (QueryModel), new SearchModelBinder());

這樣我們就可以在Action中擷取到相應的查詢條件了

我們可以看到,從表單提交過來的資料我們已經正確地存放在QueryModel中了。

 

ASP.NET MVC & EF 構建智能查詢 一、智能查詢的需求與設計

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.