将定义查询模型转换成Lambda表达式

在进行lambda进行查询时,可能我们的查询原始条件不是lambda表达式树的形式,这时我们如何将其处理组装成lambda表达式树呢,下面的例子就是将一个对象的字体,运算符,值进行组装的例子
public enum SearchMethod
    {
        /// <summary>
        /// 等于
        /// </summary>
        Equal = 0,

        /// <summary>
        /// 小于
        /// </summary>
        LessThan = 1,

        /// <summary>
        /// 大于
        /// </summary>
        GreaterThan = 2,

        /// <summary>
        /// 小于等于
        /// </summary>
        LessThanOrEqual = 3,

        /// <summary>
        /// 大于等于
        /// </summary>
        GreaterThanOrEqual = 4,

        /// <summary>
        /// Like
        /// </summary>
        Like = 5,
        /// <summary>
        /// 不等于
        /// </summary>
        NotEqual = 6
    }

定义方法:
/// <summary>
        /// 将条件组合成一个表达示
        /// </summary>
        /// <typeparam name="T">类</typeparam>
        /// <param name="field">类的字段</param>
        /// <param name="method">条件方法</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateExpression<T>(string field,SearchMethod method,object value) where T:class
        {
            ParameterExpression left = Expression.Parameter(typeof(T), "m");//m=>
            Expression right = null;
            switch (method)
            {
                case SearchMethod.Equal:
                    right = Expression.Equal(Expression.Property(left, typeof(T).GetProperty(field))
                       , Expression.Constant(value));
                    break;
                case SearchMethod.GreaterThan:
                    right = Expression.GreaterThan(Expression.Property(left, typeof(T).GetProperty(field))
                       , Expression.Constant(value));
                    break;
                case SearchMethod.GreaterThanOrEqual:
                    right = Expression.GreaterThanOrEqual(Expression.Property(left, typeof(T).GetProperty(field))
                       , Expression.Constant(value));
                    break;
                case SearchMethod.LessThan:
                    right = Expression.LessThan(Expression.Property(left, typeof(T).GetProperty(field))
                       , Expression.Constant(value));
                    break;
                case SearchMethod.LessThanOrEqual:
                    right = Expression.LessThanOrEqual(Expression.Property(left, typeof(T).GetProperty(field))
                        , Expression.Constant(value));
                    break;
                case SearchMethod.Like:
                    right = Expression.Call
                     (
                        Expression.Property(left, typeof(T).GetProperty(field)),  //m.DataSourceName
                        typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法                         
                        Expression.Constant(value)           // .Contains(optionName)
                     );
                    break;
                case SearchMethod.NotEqual:
                    right = Expression.NotEqual(Expression.Property(left, typeof(T).GetProperty(field))
                        , Expression.Constant(value));
                    break;
            }
            Expression<Func<T, bool>> finalExpression
             = Expression.Lambda<Func<T, bool>>(right, new ParameterExpression[] { left });
            return finalExpression;
        }

使用例子:
 class Program
    {
        static void Main(string[] args)
        {

            var d = Search(ExpressionHelper.CreateExpression<Student>("Age",SearchMethod.LessThan,12));


            Console.ReadLine();
        }
        static IList<Student> Search(Expression<Func<Student, bool>> expr)
        {
            return Data.Where(expr).ToList();
        }
        static IQueryable<Student> Data
        {
            get
            {
                var list = new List<Student>();
                list.Add(new Student("张三",16,DateTime.Parse("2013-12-22")));
                list.Add(new Student("李四", 16, DateTime.Parse("2013-12-22")));
                list.Add(new Student("王五", 16, DateTime.Parse("2013-12-22")));
                return list.AsQueryable();
            }
        }
       
    }
    class Student
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public DateTime Bir { get; set; }
        public Student(string name, int age, DateTime bir)
        {
            this.Age = age;
            this.Name = name;
            this.Bir = bir;
        }
    }

表达示转换有一些问题,遇到属性可为空类型会出错,可改成这样:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace ConsoleApplication6
{
    public class ExpressionHelper
    {
        /// <summary>
        /// 将条件组合成一个表达示
        /// </summary>
        /// <typeparam name="T">类</typeparam>
        /// <param name="field">类的字段</param>
        /// <param name="method">条件方法</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateExpression<T>(string field,SearchMethod method,object value) where T:class
        {
            ParameterExpression left = Expression.Parameter(typeof(T), "m");//m=>
            Expression right = null;
            switch (method)
            {
                case SearchMethod.Equal:
                    right = Expression.Equal(Expression.Convert(Expression.Property(left, typeof(T).GetProperty(field)), value.GetType())
                       , Expression.Constant(value));
                    break;
                case SearchMethod.GreaterThan:
                    right = Expression.GreaterThan(Expression.Convert(Expression.Property(left, typeof(T).GetProperty(field)), value.GetType())
                       , Expression.Constant(value));
                    break;
                case SearchMethod.GreaterThanOrEqual:
                    right = Expression.GreaterThanOrEqual(Expression.Convert(Expression.Property(left, typeof(T).GetProperty(field)), value.GetType())
                       , Expression.Constant(value));
                    break;
                case SearchMethod.LessThan:
                    var b = IsNullableType(typeof(T).GetProperty(field).PropertyType);
                    //right = Expression.LessThan(Expression.Property(left, typeof(T).GetProperty(field))
                    //   , Expression.Constant(value));
                    right = Expression.LessThan(Expression.Convert(Expression.Property(left, typeof(T).GetProperty(field)), value.GetType())
                       , Expression.Constant(value));
                    break;
                case SearchMethod.LessThanOrEqual:
                    right = Expression.LessThanOrEqual(Expression.Convert(Expression.Property(left, typeof(T).GetProperty(field)), value.GetType())
                        , Expression.Constant(value));
                    break;
                case SearchMethod.Like:
                    right = Expression.Call
                     (
                        Expression.Convert(Expression.Property(left, typeof(T).GetProperty(field)), value.GetType()),  //m.DataSourceName
                        typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法                         
                        Expression.Constant(value)           // .Contains(optionName)
                     );
                    break;
                case SearchMethod.NotEqual:
                    right = Expression.NotEqual(Expression.Convert(Expression.Property(left, typeof(T).GetProperty(field)), value.GetType())
                        , Expression.Constant(value));
                    break;
            }
            Expression<Func<T, bool>> finalExpression
             = Expression.Lambda<Func<T, bool>>(right, new ParameterExpression[] { left });
            return finalExpression;
        }
        public static Expression<Func<T, bool>> CreateExpression<T>(Expression<Func<T, object>> expr, SearchMethod method, object value) where T : class
        {
            var field = GetNameByExpress<T>(expr);
            return CreateExpression<T>(field,method,value);
        }

        private static string GetNameByExpress<T>(Expression<Func<T, object>> expr) where T : class
        {
            var pname = "";
            if (expr.Body is UnaryExpression)
            {
                var uy = expr.Body as UnaryExpression;
                pname = (uy.Operand as MemberExpression).Member.Name;
            }
            else
            {
                pname = (expr.Body as MemberExpression).Member.Name;
            }

            return pname;

        }
        private static bool IsNullableType(Type theType)
        {
            return (theType.IsGenericType && theType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)));
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值