• 基于Linq表达式做的一个简单的表达式生成器


    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Linq;
    using System.Linq.Expressions;
    
    namespace Model
    {
        [NotMapped]
        public class FilterInfo
        {
            /// <summary>
            /// 字段名称
            /// </summary>
            public string FieldName { get; set; }
            /// <summary>
            /// 字段值
            /// </summary>
            public object FieldValue { get; set; }
            /// <summary>
            /// 操作符
            /// </summary>
            public FilterOperator Operator { get; set; }
            /// <summary>
            /// 构建表达式
            /// </summary>
            /// <returns></returns>
            public Func<T, bool> BuildExpression<T>()
            {
                var constEexp = Expression.Constant(FieldValue, this.FieldValue.GetType());
                var paramExp = Expression.Parameter(typeof(T), "x");
                Expression expLeft = null;
                var tp = typeof(T);
                //基元类型直接去paramExp,自定义类型取PropExp
                if (!tp.IsPrimitive && tp != typeof(string))
                {
                    expLeft = (Expression)Expression.Property(paramExp, FieldName);
                }
                else
                {
                    expLeft = paramExp;
                }
                Expression bExp = null;
                switch (Operator)
                {
                    case FilterOperator.GreaterThan://>
                        bExp = Expression.GreaterThan(expLeft, constEexp);
                        break;
                    case FilterOperator.GreaterThanOrEqual://>=
                        bExp = Expression.GreaterThanOrEqual(expLeft, constEexp);
                        break;
                    case FilterOperator.LessThan://<
                        bExp = Expression.LessThan(expLeft, constEexp);
                        break;
                    case FilterOperator.LessThanOrEqul://<=
                        bExp = Expression.LessThanOrEqual(expLeft, constEexp);
                        break;
                    case FilterOperator.OrElse://!=
                        bExp = Expression.NotEqual(expLeft, constEexp);
                        break;
                    case FilterOperator.Like:
                        if (this.FieldValue.GetType() != typeof(string))
                        {
                            throw (new Exception("Like只能用于string类型的字段操作"));
                        }
                        bExp = Expression.Call(typeof(FilterInfo).GetMethod("Contains", new Type[] { typeof(string), typeof(string) }), expLeft, constEexp);
                        break;
                    default://=
                        bExp = Expression.Equal(expLeft, constEexp);
                        break;
                }
                var exp = Expression.Lambda<Func<T, bool>>(bExp, paramExp);
                Console.WriteLine(exp);
                return exp.Compile();
            }
            /// <summary>
            /// 用该静态方法实现like
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static bool Contains(string a, string b)
            {
                if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b))
                {
                    return false;
                }
                return a.Contains(b);
            }
        }
        /// <summary>
        /// 操作符枚举
        /// </summary>
        public enum FilterOperator
        {
            /// <summary>
            /// >
            /// </summary>
            GreaterThan,
            /// <summary>
            /// =
            /// </summary>
            Equal,
            /// <summary>
            /// <
            /// </summary>
            LessThan,
            /// <summary>
            /// <=
            /// </summary>
            LessThanOrEqul,
            /// <summary>
            /// >=
            /// </summary>
            GreaterThanOrEqual,
            /// <summary>
            /// !=
            /// </summary>
            OrElse,
            /// <summary>
            /// contain
            /// </summary>
            Like
        }
    }

    使用该表达式生成器,可以生成简单的匿名查询函数来过滤查询结果。如果我们在项目中用了EF框架,就可以在业务层中通过这个类来构建查询条件然后传到DAL层来执行,使用方法如下:

     //整形数组查询
                int[] nums = { 5, 4, 2, 2, 9, 8, 6, 7, 2, 0 };
                FilterInfo filterInt = new FilterInfo() { FieldName = "x", FieldValue = 2, Operator = FilterOperator.LessThanOrEqul };
                var intFunc = filterInt.BuildExpression<int>();
                var r = nums.Where(intFunc);
                foreach (var i in r)
                {
                    Console.WriteLine(i);
                }
                Console.WriteLine("int array search complete");
                //字符串数组查询
                string[] strArray = { "string1", "string11", "string2", "string2134", "stringOld" };
                FilterInfo f = new FilterInfo() { FieldName = "x", FieldValue = "1", Operator = FilterOperator.Like };
                var fc = f.BuildExpression<string>();
                strArray.Where(fc).ToList().ForEach(s => Console.WriteLine(s));
                //对象列表查询
                List<Org> orglist = new List<Org>();
                orglist.Add(new Org() { Guid = Guid.NewGuid().ToString(), Name = "spring" });
                for (int i = 0; i < 10; i++)
                {
                    orglist.Add(new Org() { Guid = Guid.NewGuid().ToString(), Name = "orgName" + Guid.NewGuid().ToString() });
                }
                FilterInfo filter = new FilterInfo() { FieldName = "Name", FieldValue = "Name", Operator = FilterOperator.Like };
                var func = filter.BuildExpression<Org>();
                var orgSearchList = orglist.Where(func);
                foreach (var o in orgSearchList)
                {
                    Console.WriteLine(o.Name);
                }
                Console.WriteLine("org list search Complete");
  • 相关阅读:
    如何动态调用WebServices
    Cache及(HttpRuntime.Cache与HttpContext.Current.Cache)
    SQL创建索引(转)
    TSQL用法四:OpenDataSource, OpenRowSet
    AppDomain动态加载程序集
    hdu 2544 最短路
    hdu 1151 Air Raid
    hdu3790 最短路径问题
    hdu 1548 A strange lift
    对于 前K短路径问题 和 A*算法 的一些小小总结
  • 原文地址:https://www.cnblogs.com/yyq745201/p/5051351.html
Copyright © 2020-2023  润新知