zoukankan      html  css  js  c++  java
  • EF+MVC动态Lamda表达式拼接(学习笔记)

      最近一段时间比较闲,看到项目中有一个比较有意思的东西,没错就是C# Expression类,那它能干嘛呢,有兴趣的朋友可以看一下微软官方的文档,https://msdn.microsoft.com/zh-cn/library/system.linq.expressions.expression(v=vs.100).aspx。好了话不多说,直接看案例:

      场景:在做后端查询的时候,按照传统的做法我们声明一个查询类,然后再写if判断来拼接各种条件,日后我们页面每添加一个条件,我们需要在逻辑层增加相应判断,这样,我每写一张表的查询,我都需要写一个查询类,有同学可能想到,没关系,我把每个表对应的每个字段都先在底层处理好,日后在前端只需要增加相应的字段了!对没错,要是一个类有10个字段,但只有5个字段是查询字段,或者后面需求又加到6个字段.......做开发的你当然没问题,加一个条件,编译生成DLL,发布,后面业务又要加一个(心想:沃日,你能不能一次说好.....)。说到这里呢,也许你发现好像真是这样的,有没有好的方法解决呢? 接下来,我将跟着你一起思考这个问题。

      思考:要是我能在前端直接传来一些条件,根据这些东西我能动态生成Lamda表达式,这样我每添加一个条件只要前端改改,直接上线,发布都免了,那多省事啊。

      好的,到这里我们先准备一个实体类,如下:

         

       接下来,我们先看看Expression类的一些基本用法,这里我用代码给大家做演示

     
    string UrL ="https://shop162421329.taobao.com/?spm=a230r.7195193.1997079397.2.H0ME5j"
    

      

    public partial class User:BaseEntity<Guid>
        {
            [Required(ErrorMessage="用户姓名不能为空")]
            [DisplayName("姓名")]
            public string UserName { get; set; }
            [DisplayName("性别")]
            public Nullable<bool> UserSex { get; set; }
            [DisplayName("出生日期")]
            public Nullable<System.DateTime> UserBirthDay { get; set; }
            public string Phone1 { get; set; }
            public string Phone2 { get; set; }
            public string Phone3 { get; set; }
    
            string _url;
            public string Url 
            {
                get
                {
                    return "https://shop162421329.taobao.com/?spm=a230r.7195193.1997079397.2.H0ME5j";
                }
                set
                {
                     _url = value;
                }     
            }
        }
    View Code
    public ActionResult Index(User user =null)
            {
                var list = userManager.Get();
             //创建表达式的开始部分:p=>
                ParameterExpression parameter1 = Expression.Parameter(typeof(User), "p");
    
                if (!string.IsNullOrEmpty(user.UserName))
                {
                    //创建我们要查询的字段:p.UserName
                    MemberExpression para = Expression.Property(parameter1, "UserName");
                    
                    //给值做转换
                    ConstantExpression value = Expression.Constant(user.UserName);
    
                    //创建我们要查询的字段: p.UserName==‘测试1’
                    var query1 = Expression.Equal(para, value);
    
    
                     //创建我们要查询的字段:p.UserName
                    MemberExpression para2 = Expression.Property(parameter1, "Phone1");
                    
                    //给值做转换
                    ConstantExpression value2 = Expression.Constant(user.UserName);
    
                    var query2 = Expression.Equal(para2, value2);
    
                    var query3 = Expression.Or(query1, query2);
    
    
    
                    //构建like p=>p.UserName.Contains("")
                    Expression like = Expression.Call
                          (
                             Expression.Property(parameter1, typeof(User).GetProperty("UserName")),  //c.DataSourceName
                             typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法                         
                             Expression.Constant(user.UserName)           // .Contains(optionName)     不能使用上面组合出来的value
                          );
    
    
    
                    Expression phone1like = Expression.Call
                         (
                            Expression.Property(parameter1, typeof(User).GetProperty("Phone1")),  //c.DataSourceName
                            typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法                         
                            Expression.Constant("135")           // .Contains(optionName)     不能使用上面组合出来的value
                         );
    
    
                    Expression phone2like = Expression.Call
                      (
                         Expression.Property(parameter1, typeof(User).GetProperty("Phone2")),  //c.DataSourceName
                         typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法                         
                         Expression.Constant("135")           // .Contains(optionName)     不能使用上面组合出来的value
                      );
    
                    Expression phone3like = Expression.Call
                      (
                         Expression.Property(parameter1, typeof(User).GetProperty("Phone3")),  //c.DataSourceName
                         typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法                         
                         Expression.Constant("135")           // .Contains(optionName)     不能使用上面组合出来的value
                      );
    
    
                    var query4 = Expression.Or(phone1like, phone2like);
    
                    var q5 = Expression.Or(query4, phone3like);
    
                    var q6 = Expression.And(like, q5);
    
                    var lambda = Expression.Lambda<Func<User, Boolean>>(query1, parameter1);
    
                    list= list.AsQueryable().Where(lambda).ToList();
                   
                }
    
                return View(list);
            }
    View Code

      这样一来,你就明白Expression 的一些基本用法了,但是你可能会问  : "说好的只需要前端改改呢",犹豫项目原因,我后续会继续完善,前端大概格式如下:

      

     var where = [];
                
                var v = $("#merchant_accno").val().trim();
    
                if (v!="")
                {
                    where.push({ Join: "||", Property: "merchant_accno", Operator: "like", Value:v });
    
                }
    View Code

      到这里,我想聪明的你应该明白我接下的通用方法了,感谢以下参考文件

      http://www.2cto.com/kf/201305/213949.html;

      https://blogs.msdn.microsoft.com/meek/2008/05/02/linq-to-entities-combining-predicates/;

         http://blog.csdn.net/hao134838/article/details/51404151; 

      

        

      

  • 相关阅读:
    Dictionary(二)
    LoveTao项目源码共享
    小功能天气预报
    对XML的收集3
    小小练习:对XML的处理
    对XML的收集4
    对XML的收集2
    小小练习:测试获取用户信息接口
    大学生免费自学各种技术网址大全 不要再报班了
    DevComponents.AdvTree 相关笔记
  • 原文地址:https://www.cnblogs.com/Xty09/p/5795055.html
Copyright © 2011-2022 走看看