》》》可以借助 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());