表 达式树

》》》可以借助 LINQPad工具
csharp 复制代码
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace EFDemo
{
    public class Product
    {
        public string Product_Name { get; set; }
        public int Product_Price { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<Product> prolist = new List<Product>() {
                new Product(){ Product_Name="苹果手机",Product_Price=5999},
                new Product(){ Product_Name="华为手机",Product_Price=4999},
                new Product(){ Product_Name="华为手机",Product_Price=6999},
                new Product(){ Product_Name="苹果手机",Product_Price=9999}
            };
            var result1= prolist.Where(c =>{ return c.Product_Name == "苹果手机" && c.Product_Price > 6000; });
            foreach (var r in result1)
            {
                Console.WriteLine($"产品名称:{r.Product_Name} 价格:{r.Product_Price}");
            }
            var item=Expression.Parameter(typeof(Product), "item");
            var item_name = Expression.Property(item, "Product_Name");
            var item_price= Expression.Property(item, "Product_Price");
            var query_Name = Expression.Constant("苹果手机");
            var query_Price = Expression.Constant(6000);
            var c1 = Expression.Equal(item_name, query_Name);
            var c2 = Expression.GreaterThan(item_price, query_Price);
            var cc = Expression.And(c1, c2);
            var lambda_expression = Expression.Lambda<Func<Product, bool>>(cc, item);
            var reuslt = lambda_expression.Compile();
           
            Console.WriteLine(lambda_expression.ToString());
            var res = prolist.Where(reuslt);
            foreach (var r in res)
            {
                Console.WriteLine($"产品名称:{r.Product_Name} 价格:{r.Product_Price}");
            }
            Console.ReadKey();
        }
    }
}

》》》表达式树 编译之后 才是委托

利用表达式树 对象的映射

》》》定义一个泛型静态类 ExpressionMapper<Tin ,Tout>

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace EFDemo
{
     public class ExpressionMapper<Tin ,Tout>
    {
        private static Func<Tin, Tout> _Func = null;
        static ExpressionMapper()
        {
            ParameterExpression paramExp = Expression.Parameter(typeof(Tin), "p");
            List<MemberBinding> memberBindingList = new List<MemberBinding>();
            //绑定属性
            foreach (var item in typeof(Tout).GetProperties())
            {
                //   比如p.Product_ID
                MemberExpression member = Expression.Property(paramExp, typeof(Tin).GetProperty(item.Name)); 
                //Product_ID = p.Product_ID 
                MemberBinding memberBinding = Expression.Bind(item,member); 
                memberBindingList.Add(memberBinding);
            }
            //绑定字段
            foreach (var item in typeof(Tout).GetFields())
            {
                MemberExpression member = Expression.Field(paramExp, typeof(Tin).GetField(item.Name));
                MemberBinding memberBinding = Expression.Bind(item, member);
                memberBindingList.Add(memberBinding);
            }
             //创建新对象并初始化 
             //new Good() {Product_ID= p.Product_ID, Product_Price= p.Product_Price}
            MemberInitExpression memberInitExp = Expression.MemberInit(Expression.New(typeof(Tout)),memberBindingList.ToArray());
            //p=>new Good() {Product_ID= p.Product_ID, Product_Price= p.Product_Price}
            Expression<Func<Tin, Tout>> funcExp = Expression.Lambda<Func<Tin, Tout>>(memberInitExp, new ParameterExpression[] { paramExp });
            _Func = funcExp.Compile();
        }

        public static Tout Mapper(Tin t)
        {
            return _Func(t);
        }
    }
}

》》》 使用.netFramwork框架自带的AutoMapper,首先我们要nuget添加引用AutoMapper即可直接使用,具体代码为:

csharp 复制代码
using AutoMapper;

namespace ExpressionDemo.MappingExtend
{
    public class AutoMapperTest
    {
        public static TOut Trans<TIn, TOut>(TIn tIn)
        {
            return Mapper.Instance.Map<TOut>(tIn);
        }
    }
}

》》》利用反射

csharp 复制代码
/// <summary>
        /// 反射
        /// </summary>
        /// <typeparam name="TIn"></typeparam>
        /// <typeparam name="TOut"></typeparam>
        /// <param name="tIn"></param>
        /// <returns></returns>
        public static TOut Trans<TIn, TOut>(TIn tIn)
        {
            TOut tOut = Activator.CreateInstance<TOut>();
            foreach (var itemOut in tOut.GetType().GetProperties())
            {
                var propIn = tIn.GetType().GetProperty(itemOut.Name);
                itemOut.SetValue(tOut, propIn.GetValue(tIn));
            }
            foreach (var itemOut in tOut.GetType().GetFields())
            {
                var fieldIn = tIn.GetType().GetField(itemOut.Name);
                itemOut.SetValue(tOut, fieldIn.GetValue(tIn));
            }
            return tOut;
        }

》》》 使用序列化和反序列化来完成对象属性映射:

csharp 复制代码
/// <summary>
    /// 使用第三方序列化反序列化工具
    /// 
    /// 还有automapper
    /// </summary>
    public class SerializeMapper
    {
        /// <summary>
        /// 序列化反序列化方式
        /// </summary>
        /// <typeparam name="TIn"></typeparam>
        /// <typeparam name="TOut"></typeparam>
        public static TOut Trans<TIn, TOut>(TIn tIn)
        {
            return JsonConvert.DeserializeObject<TOut>(JsonConvert.SerializeObject(tIn));
        }
    }

》》》用lambda 生成 表达式

Lambda使用lambda表达声明表达式目录树的时候注意不能有{},即:

csharp 复制代码
Expression<Func<int, int, int>> exp1 = (m, n) =>
  {
          return m * n + 2;
  };//不能有语句体   只能是一行,不能有大括号
csharp 复制代码
  internal static class SqlOperator
    {
        internal static string ToSqlOperator(this ExpressionType type)
        {
            switch (type)
            {
                case (ExpressionType.AndAlso):
                case (ExpressionType.And):
                    return "AND";
                case (ExpressionType.OrElse):
                case (ExpressionType.Or):
                    return "OR";
                case (ExpressionType.Not):
                    return "NOT";
                case (ExpressionType.NotEqual):
                    return "<>";
                case ExpressionType.GreaterThan:
                    return ">";
                case ExpressionType.GreaterThanOrEqual:
                    return ">=";
                case ExpressionType.LessThan:
                    return "<";
                case ExpressionType.LessThanOrEqual:
                    return "<=";
                case (ExpressionType.Equal):
                    return "=";
                case ExpressionType.Subtract:
                    return "-";
                default:
                    throw new Exception("不支持该方法");
            }

        }
    }
  public class CustomVisitor : ExpressionVisitor
    {
        private Stack<string> _StringStack = new Stack<string>();

        public string Condition()
        {
            string condition = string.Concat(this._StringStack.ToArray());
            this._StringStack.Clear();
            return condition;
        }

        /// <summary>
        /// 如果是二元表达式
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        protected override Expression VisitBinary(BinaryExpression node)
        {
            if (node == null) throw new ArgumentNullException("BinaryExpression");

            this._StringStack.Push(")");
            base.Visit(node.Right);//解析右边
            this._StringStack.Push(" " + node.NodeType.ToSqlOperator() + " ");
            base.Visit(node.Left);//解析左边
            this._StringStack.Push("(");

            return node;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        protected override Expression VisitMember(MemberExpression node)
        {
            if (node == null) throw new ArgumentNullException("MemberExpression");
            this._StringStack.Push(" [" + node.Member.Name + "] ");
            return node;
        }
        /// <summary>
        /// 常量表达式
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        protected override Expression VisitConstant(ConstantExpression node)
        {
            if (node == null) throw new ArgumentNullException("ConstantExpression");
            this._StringStack.Push(" '" + node.Value + "' ");
            return node;
        }
        /// <summary>
        /// 方法表达式
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            if (m == null) throw new ArgumentNullException("MethodCallExpression");

            string format;
            switch (m.Method.Name)
            {
                case "StartsWith":
                    format = "({0} LIKE {1}+'%')";
                    break;

                case "Contains":
                    format = "({0} LIKE '%'+{1}+'%')";
                    break;

                case "EndsWith":
                    format = "({0} LIKE '%'+{1})";
                    break;

                default:
                    throw new NotSupportedException(m.NodeType + " is not supported!");
            }
            this.Visit(m.Object);
            this.Visit(m.Arguments[0]);
            string right = this._StringStack.Pop();
            string left = this._StringStack.Pop();
            this._StringStack.Push(String.Format(format, left, right));

            return m;
        }
      
    }
csharp 复制代码
 Expression<Func<People, bool>> lambda = x => x.Age > 5 && x.Name == "A" || x.Id > 5;
                CustomVisitor vistor = new CustomVisitor();
                vistor.Visit(lambda);
                Console.WriteLine(vistor.Condition());
相关推荐
一丝晨光6 小时前
Java、PHP、ASP、JSP、Kotlin、.NET、Go
java·kotlin·go·php·.net·jsp·asp
yufei-coder7 小时前
C#基础语法
开发语言·c#·.net
Mudrock__8 小时前
前后端传输文件(图片)
vue·.net
时光追逐者2 天前
WaterCloud:一套基于.NET 8.0 + LayUI的快速开发框架,完全开源免费!
前端·microsoft·开源·c#·.net·layui·.netcore
friklogff2 天前
【C#生态园】打造现代化跨平台应用:深度解析.NET桌面应用工具
开发语言·c#·.net
@Unity打怪升级2 天前
【C#】CacheManager:高效的 .NET 缓存管理库
开发语言·后端·机器学习·缓存·c#·.net·.netcore
yufei-coder3 天前
.Net 9与AI开发
人工智能·.net
孟章豪3 天前
深入理解.NET中的委托与事件:实现灵活的事件驱动编程
.net
小彰5 天前
.Net 6.0 Windows平台如何判断当前电脑是否联网
windows·.net
小码编匠5 天前
.NET 中的表达式树(Expression Trees)
后端·c#·.net