一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - Asp.net中使用DapperExtensions和反射來實現一個通用搜索

Asp.net中使用DapperExtensions和反射來實現一個通用搜索

2020-04-24 14:42yt1983 ASP.NET教程

這篇文章主要介紹了Asp.net中使用DapperExtensions和反射來實現一個通用搜索功能,非常不錯,具有參考解決價值,需要的朋友可以參考下

前言

  搜索功能是一個很常用的功能,當然這個搜索不是指全文檢索,是指網站的后臺管理系統或ERP系統列表的搜索功能。常見做法一般就是在搜索欄上加上幾個常用字段來搜索。代碼可能一般這樣實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
StringBuilder sqlStr = new StringBuilder();
if (!string.IsNullOrEmpty(RealName))
{
  sqlStr.Append(" and RealName = @RealName");
}
if (Age != -1)
{
  sqlStr.Append(" and Age = @Age");
}
if (!string.IsNullOrEmpty(StartTime))
{
  sqlStr.Append(" and CreateTime >= @StartTime");
}
if (!string.IsNullOrEmpty(EndTime))
{
  sqlStr.Append(" and CreateTime <= @EndTime");
}
MySqlParameter[] paras = new MySqlParameter[]{
      new MySqlParameter("@Age", Age),
      new MySqlParameter("@RealName", RealName),
      new MySqlParameter("@StartTime", StartTime),
      new MySqlParameter("@EndTime", EndTime)
    };

 這段代碼如果遇到下面幾個需求,又該如何處理?

  1. 再加一個查詢字段
  2. RealName需要改成模糊查詢
  3. Age需要支持范圍查詢

可能大多數程序猿想法,這是新的需求,那么就直接改代碼,簡單粗暴。然后在前臺加個age范圍文本框,后臺再加個if判斷,realname的=號就直接改成like,就這樣輕松搞定了。但需求總是不斷變化,如果一張表有50個字段,同時需要支持其中40個字段查詢。我想大都數人第一反應:臥槽,神經病!難道就沒有一個通用的辦法來解決這種搜索的問題?我想說當然有,本文接下來就用DapperExtensions和反射的來解決這個問題,最終于實現的效果如下圖:

Asp.net中使用DapperExtensions和反射來實現一個通用搜索

DapperExtensions介紹

  DapperExtensions是基于Dapper的一個擴展,主要在Dapper基礎上實現了CRUD的操作。它還提供了一個謂詞系統,可以實現更多復雜的高級查詢功能。還可以通過ClassMapper來定義實體類和表的映射。

通用搜索功能實現

1.首先創建一個account表,然后增加一個Account類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Account
  {
    public Account()
    {
      Age = -1;
    }
    /// <summary>
    /// 賬戶ID
    /// </summary>
    [Mark("賬戶ID")]
    public int AccountId { get; set; }
    /// <summary>
    /// 姓名
    /// </summary>
    [Mark("姓名")]
    public string RealName { get; set; }
    /// <summary>
    /// 年齡
    /// </summary>
    [Mark("年齡")]
    public int Age { get; set; }
    /// <summary>
    /// 創建時間
    /// </summary>
    [Mark("創建時間")]
    public DateTime CreateTime { get; set; }
  }

2.為了獲取字段對應的中文名稱,我們增加一個MarkAttribute類。因為有強大的反射功能,我們可以通過反射動態獲取每張表實體類的屬性和中文名稱。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
  public class MarkAttribute : Attribute
  {
    public MarkAttribute(string FiledName, string Description = "")
    {
      this.FiledName = FiledName;
      this.Description = Description;
    }
    private string _FiledName;
    public string FiledName
    {
      get { return _FiledName; }
      set { _FiledName = value; }
    }
    private string _Description;
    public string Description
    {
      get { return _Description; }
      set { _Description = value; }
    }
  }

3.通用搜索思路主要是把搜索功能抽象出一個對象,本質上也就列名、操作符、值組成的一個對象集合,這樣就可以實現多個搜索條件的組合。我們增加一個Predicate類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Predicate
  {
    /// <summary>
    /// 列名
    /// </summary>
    public string ColumnItem { get; set; }
    /// <summary>
    /// 操作符
    /// </summary>
    public string OperatorItem { get; set; }
    /// <summary>
    /// 值
    /// </summary>
    public object Value { get; set; }
  }

4.然后通過反射Account類的屬性加載到前臺列名的DropDownList,再增加一個操作符的DropDownList

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var columnItems = new List<SelectListItem>();
      //通過反射來獲取類的屬性
      Type t = Assembly.Load("SearchDemo").GetType("SearchDemo.Models.Account");
      foreach (PropertyInfo item in t.GetProperties())
      {
        string filedName = (item.GetCustomAttributes(typeof(MarkAttribute), false)[0] as MarkAttribute).FiledName;
        columnItems.Add(new SelectListItem() { Text = filedName, Value = item.Name });
      }
      ViewBag.columnItems = columnItems;
      var operatorItems = new List<SelectListItem>()
      {
        new SelectListItem() {Text = "等于", Value = "Eq"},
        new SelectListItem() {Text = "大于", Value = "Gt"},
        new SelectListItem() {Text = "大于或等于", Value = "Ge"},
        new SelectListItem() {Text = "小于", Value = "Lt"},
        new SelectListItem() {Text = "小于或等于", Value = "Le"},
        new SelectListItem() {Text = "模糊", Value = "Like"}
      };
      ViewBag.operatorItems = operatorItems;

 5.前臺界面實現代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<!DOCTYPE html>
<html>
<head>
  <title>DapperExtensions通用搜索</title>
  <script src="../../Scripts/jquery-1.4.4.min.js" type="text/javascript"></script>
  <script type="text/javascript">
    Date.prototype.format = function (format) {
      var o = {
        "M+": this.getMonth() + 1, //month 
        "d+": this.getDate(), //day 
        "h+": this.getHours(), //hour 
        "m+": this.getMinutes(), //minute 
        "s+": this.getSeconds(), //second 
        "q+": Math.floor((this.getMonth() + 3) / 3), //quarter 
        "S": this.getMilliseconds() //millisecond 
      }
      if (/(y+)/.test(format)) {
        format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
      }
      for (var k in o) {
        if (new RegExp("(" + k + ")").test(format)) {
          format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
        }
      }
      return format;
    }
  </script>
  <style type="text/css">
    ul
    {
      list-style: none;
      padding: 0px;
      margin: 0px;
      width: 590px;
      height: 20px;
      line-height: 20px;
      border: 1px solid #99CC00;
      border-top: 0px;
      font-size: 12px;
    }
    ul li
    {
      display: block;
      width: 25%;
      float: left;
      text-indent: 2em;
    }
    .th
    {
      background: #F1FADE;
      font-weight: bold;
      border-top: 1px solid #99CC00;
    }
  </style>
  <script type="text/javascript">
    var predicates = [];
    var index = 0;
    $(document).ready(function () {
      $("#btnAdd").click(function () {
        var columnItem = $("#columnItems option:selected");
        var operatorItem = $("#operatorItems option:selected");
        var value = $("#value").val();
        if(value == ""){
          alert("請輸入值");
          return;
        }
        var predicate = { index: index, columnItem: columnItem.val(), operatorItem: operatorItem.val(), value: value };
        predicates.push(predicate);
        var html = "<ul><li>" + columnItem.text() + "</li><li>" + operatorItem.text() + "</li><li>" + value + "</li><li><a href='javascript:;' onclick='del(this," + index + ")'>刪除</a></li></ul>"
        $("#predicates ul:last").after(html);
        index++;
      })
      $("#btnSearch").click(function () {
        $.ajax({
          type: "POST",
          url: "home/search",
          data: JSON.stringify(predicates),
          contentType: "application/json",
          success: function (data) {
            if (data.Error != null) {
              alert(data.Error);
              return;
            }
            $("#list .th").nextAll().remove();
            var html = "";
            $.each(data, function (index, item) {
              html += "<ul><li>" + item.AccountId + "</li>";
              html += "<li>" + item.RealName + "</li>";
              html += "<li>" + item.Age + "</li>";
              //轉換日期
              var dateMilliseconds = parseInt(item.CreateTime.replace(/\D/igm, ""));
              var date = new Date(dateMilliseconds);
              html += "<li>" + date.format("yyyy-MM-dd hh:mm:ss") + "</li></ul>";
            });
            $("#list .th").after(html);
          }
        });
      })
    })
    function del(obj,index) {
      obj.parentNode.parentNode.remove();
      for (var i = 0; i < predicates.length; i++) {
        if (predicates[i].index == index) {
          predicates.splice(i, 1);
        }
      }
    }
  </script>
</head>
<body>
  <div>
    列名:@Html.DropDownList("columnItems")  操作符:@Html.DropDownList("operatorItems")  值:@Html.TextBox("value")  
    <input id="btnAdd" type="button" value="增加" />  <input id="btnSearch" type="button" value="搜索" />
  </div>
  <br />
  <div id="predicates">
    <ul class="th">
      <li>列名</li>
      <li>操作符</li>
      <li>值</li>
      <li>操作</li>
    </ul>
  </div>
  <br />
  <div id="list">
    <ul class="th">
      <li>賬戶ID</li>
      <li>姓名</li>
      <li>年齡</li>
      <li>創建時間</li>
    </ul> 
  </div>
</body>
</html>

 6.最后通過DapperExtensions的謂詞和反射實現搜索方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[HttpPost]
   public JsonResult Search(List<Predicate> predicates)
   {
     if (predicates == null)
     {
       return Json(new { Error = "請增加搜索條件" });
     }
     using (var connection = SqlHelper.GetConnection())
     {
       var pga = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
       foreach (var p in predicates)
       {
         var predicate = Predicates.Field<Account>(GetExpression(p), (Operator)Enum.Parse(typeof(Operator), p.OperatorItem), p.Value);
         pga.Predicates.Add(predicate);
       }
       var list = connection.GetList<Account>(pga);
       return Json(list);
     }
   }
   private static Expression<Func<Account, object>> GetExpression(Predicate p)
   {
     ParameterExpression parameter = Expression.Parameter(typeof(Account), "p");
     return Expression.Lambda<Func<Account, object>>(Expression.Convert(Expression.Property(parameter, p.ColumnItem), typeof(object)), parameter);
   }

  最終,通過簡單的幾行代碼,在基于DapperExtensions的功能基礎上,我們最終實現了一個可以支持多個字段、多個條件、多個操作符的通用查詢功能。本文也只是拋磚引玉,只是提供一種思路,還有更多細節沒有考慮。比如多個條件的組合可以再增加一個邏輯符來連接、多個條件組合嵌套查詢、多表查詢等等。

以上所述是小編給大家介紹的Asp.net中使用DapperExtensions和反射來實現一個通用搜索,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

原文鏈接:http://www.cnblogs.com/yt1983/p/6485499.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲精品一区二区三区在线播放 | 亚洲国产精品嫩草影院永久 | 国产短视频精品一区二区三区 | 天天操天天射天天色 | 美女的让男人桶爽30分钟的 | 被18号每天强行榨干acg | melody中文字幕| 日本一区二区免费在线观看 | 被18号每天强行榨干acg | 日韩欧美高清一区 | 国产成人综合久久精品红 | 亚洲精品综合一二三区在线 | 国产大秀视频一区二区三区 | 国产精品第四页 | 啪一啪在线视频 | 成人精品网 | 青草网在线观看 | 天天做天天爱天天一爽一毛片 | 欧美日韩国产成人精品 | brazzersvideo欧美最新 | 美女牲交毛片一级视频 | 女人把私密部位张开让男人桶 | 欧美日韩在线观看一区二区 | 999精品视频在线观看热6 | 免费人成在线观看视频播放 | 国产精品久久国产三级国电话系列 | 天天欲色成人综合网站 | 99草视频 | 91香蕉国产在线观看免费永久 | 99久久国产综合精品麻豆 | 国产精品刺激好大好爽视频 | 免费在线公开视频 | 国产精品一区三区 | 久久三级视频 | 紧身短裙女教师波多野 | 国产一级片免费观看 | 日本中文字幕在线视频 | 91精品免费国产高清在线 | 欧美一级高清片免费一级 | 国产欧美日韩免费一区二区 | 亚洲精品综合一区二区 |