• ASP.NET MVC & EF 构建智能查询 一、智能查询的需求与设计


    关于复用

    在我们日常的开发过程中,代码的复用其实是很重要的一部分,ASP.NET MVC框架本身为我们提供了很多很好的复用机制,让我们能充分地利用它们来节省我们的Coding成本。

    在简单的Coding中,我们可以通过构造方法来实现代码段的复用,在OOP编程中我们可以使用继承多态来进行类的复用,我们也可以使用设计模式来做类或对象间的代码设计的复用,随着程序的复杂我们就想构造出更佳的复用方式,可以向更高层次上抽象。

    应用场景与目标

    在信息管理系统中我们会开发大量的List页面,它们功能上通常是非常相似的,一般是包含一个查询条件组和一个列表。

    例如下图所示

    image

    那我的目标呢,就是对这里面的查询功能进行封装,以达到“只要更改页面上的条件,就可以实现自动的查询逻辑”这样的功能,即:如果我们要加一个查询条件则不需要修改逻辑代码只修改页面即可。

    其实对于一个有经验的开发人员呢,根据HTML页面的查询条件去自动生成查询结果并不是难事。最简单的是将查询提交表单遍历,然后连接成一个SQL进行查询。

    但是使用SQL有很多问题

    1. 注入问题,因为不知道类型,所以很多地方都要拼写引号就算是使用Parameter,也无法处理类型转换的问题
    2. 无法处理Or和And共存的问题
    3. 无法处理其它查询条件如大于小于Like

    那我们想一下我们使用EF的话是如何正常去编写一个查询的呢

    我们通常是在逻辑中去拼SQL或是写如下的EF:

       1: var query = db.User.AsQueryable();
       2: if (string.IsNullOrEmpty(name))
       3:     query = query.Where(c => c.Name == name);
       4: if (id.HasValue)
       5:     query = query.Where(c => c.Id == id);
       6: if (string.IsNullOrEmpty(email))
       7:     query = query.Where(c => c.Email == email);
       8: return query.ToList();

    那我们的目标其实就明确了,我们就是要让代码自动去完成上述这一过程,并且可以支持

    1. 识别类型(EF的话这个很重要)
    2. 仅查询有效条件
    3. 处理可空类型
    4. 处理类型转换(如DateTime与UnixTime的转换)
    5. 一些代码性逻辑(比如查询某些日期的时候,其实我们要的结果并不是c=>c.Time==time而是c=>c.Time>time && c.Time<time.AddDays(1))
    6. 支持Or等 混合查询
    7. 关于Like的相关处理
    8. 关于In操作的相关处理
    9. Join查询的相关处理

    理论流程

    看一看我们要做的其实还挺多的,但是我已经在心里搭出了一个这样的流程,使用ASP.NET MVC及EF特性来完成这些功能

    image

    那其实呢首先的问题就是我们从浏览器请求向服务器的时候,除了要查询的字段,还应该包含有 怎么查(就是操作符,比如= < > like in)、是否为Or、

    而HTML中唯一可以直接传到服务器的就是表单元素的name所以我们可以对name来做一些手脚让它包含这些信息

    比如[Equal]Id就表示让Id这个属性的值等于这个表单项的Value

    [Equal]Id=1

    我们就利用这个postdata或QueryString去构造出

    c=>c.Id==1的Lambda表达式,并且支持多个条件

    实际实现

    而我是在Helper上加了一层扩展来实现这样的功能的,形如

       1: <form action="" method="post">
       2: 姓名:@Html.TextBox("Name").ForSearch(QueryMethod.Like)   
       3: Email:@Html.TextBox("Email").ForSearch(QueryMethod.Equal)<br />
       4: Id: @Html.TextBox("Id").ForSearch(QueryMethod.Equal)
       5: 生日: @Html.TextBox("Birthday").ForSearch(QueryMethod.Equal)<br />
       6: <input type="submit" value="查询" />
       7: </form>

    这里我们使用ForSearch这个扩展为Html的name添加了前置的谓词标记[Equal]

    我们在服务器端只要统一处理

       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:  
       9: }

    我们是在这个Where的扩展方法里重写了将QueryModel转换成lambda表达式的工作,当然在这之前我们还利用了自已实现的ModelBinder去将 postdata/querystring进行了分析前初始化了QueryModel

    在未来的几篇中我们将会详述这些过程的实现

    ASP.NET MVC & EF 构建智能查询 二、模型的设计与ModelBinder

  • 相关阅读:
    基于Python的人脸动漫转换
    let 与 var的区别
    【LeetCode】汇总
    【HDU】4632 Palindrome subsequence(回文子串的个数)
    【算法】均匀的生成圆内的随机点
    【LeetCode】725. Split Linked List in Parts
    【LeetCode】445. Add Two Numbers II
    【LeetCode】437. Path Sum III
    【LeetCode】222. Count Complete Tree Nodes
    【LeetCode】124. Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/chsword/p/searchmodel_1.html
Copyright © 2020-2023  润新知