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; 

  

    

  

 

转载于:https://www.cnblogs.com/Xty09/p/5795055.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值