c# Expression<Func<T, T>>转成实体
将 Expression<Func<T, T>>转成实体T
public class MyEntity
{
public int Age { get; set; }
public string Name { get; set; }
}
public static class ExpressionExtension
{
#region 表达式类型字典
/// <summary>
/// 表达式类型字典
/// </summary>
private static readonly Dictionary<ExpressionType, string> NodeTypeDic = new Dictionary<ExpressionType, string>
{
{ExpressionType.AndAlso," AND "},
{ExpressionType.OrElse," OR "},
{ExpressionType.Equal," = "},
{ExpressionType.NotEqual," != "},
{ExpressionType.LessThan," < "},
{ExpressionType.LessThanOrEqual," <= "},
{ExpressionType.GreaterThan," > "},
{ExpressionType.GreaterThanOrEqual," >= "}
};
#endregion
#region 获取表达式类型转换结果
/// <summary>
/// 获取表达式类型转换结果
/// </summary>
/// <param name="node">二元表达式</param>
/// <returns></returns>
public static string GetExpressionType(this BinaryExpression node)
{
var nodeTypeDic = NodeTypeDic[node.NodeType];
string nodeType = null;
if (node.Right.NodeType == ExpressionType.Constant && ((ConstantExpression)node.Right).Value == null)
{
switch (node.NodeType)
{
case ExpressionType.Equal:
nodeType = " IS ";
break;
case ExpressionType.NotEqual:
nodeType = " IS NOT ";
break;
}
}
return !string.IsNullOrEmpty(nodeType) ? nodeType : nodeTypeDic;
}
#endregion
#region 获取最底层成员表达式
/// <summary>
/// 获取最底层成员表达式
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public static MemberExpression GetRootMember(this MemberExpression e)
{
if (e.Expression == null || e.Expression.NodeType == ExpressionType.Constant)
return e;
return e.Expression.NodeType == ExpressionType.MemberAccess
? ((MemberExpression)e.Expression).GetRootMember()
: null;
}
#endregion
#region 转换成一元表达式并取值
/// <summary>
/// 转换成一元表达式并取值
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
public static object ToConvertAndGetValue(this Expression expression)
{
if (expression.Type != typeof(object))
expression = Expression.Convert(expression, typeof(object));
var lambdaExpression = Expression.Lambda<Func<object>>(expression);
return lambdaExpression.Compile().Invoke();
}
#endregion
public static object MemberToValue(this MemberExpression memberExpression)
{
var topMember = GetRootMember(memberExpression);
if (topMember == null)
throw new InvalidOperationException("需计算的条件表达式只支持由 MemberExpression 和 ConstantExpression 组成的表达式");
return memberExpression.MemberToValue(topMember);
}
public static object MemberToValue(this MemberExpression memberExpression, MemberExpression topMember)
{
if (topMember.Expression == null)
{
//var aquire = Cache.GetOrAdd(memberExpression.ToString(), key => GetStaticProperty(memberExpression));
var aquire = GetStaticProperty(memberExpression);
return aquire(null, null);
}
else
{
//var aquire = Cache.GetOrAdd(memberExpression.ToString(), key => GetInstanceProperty(memberExpression, topMember));
var aquire = GetInstanceProperty(memberExpression, topMember);
return aquire((topMember.Expression as ConstantExpression).Value, null);
}
}
private static Func<object, object[], object> GetInstanceProperty(Expression e, MemberExpression topMember)
{
var parameter = Expression.Parameter(typeof(object), "local");
var parameters = Expression.Parameter(typeof(object[]), "args");
var castExpression = Expression.Convert(parameter, topMember.Member.DeclaringType);
var localExpression = topMember.Update(castExpression);
var replaceExpression = ExpressionModifier.Replace(e, topMember, localExpression);
replaceExpression = Expression.Convert(replaceExpression, typeof(object));
var compileExpression = Expression.Lambda<Func<object, object[], object>>(replaceExpression, parameter, parameters);
return compileExpression.Compile();
}
private static Func<object, object[], object> GetStaticProperty(Expression e)
{
var parameter = Expression.Parameter(typeof(object), "local");
var parameters = Expression.Parameter(typeof(object[]), "args");
var convertExpression = Expression.Convert(e, typeof(object));
var compileExpression = Expression.Lambda<Func<object, object[], object>>(convertExpression, parameter, parameters);
return compileExpression.Compile();
}
public static string GetColumnAttributeName(this MemberInfo memberInfo)
{
return memberInfo.GetCustomAttribute<ColumnAttribute>()?.Name ?? memberInfo.Name;
}
public static TEntity MapToEntity<TEntity>(this Expression<Func<TEntity, TEntity>> expression)
{
TEntity entity = Activator.CreateInstance<TEntity>();
// 确保传入的是Lambda表达式
if (expression.NodeType != ExpressionType.Lambda)
throw new ArgumentException("Expression must be a lambda expression", nameof(expression));
// 获取Lambda表达式的主体,即单个MemberExpression
var body = ((LambdaExpression)expression).Body;
// 确保Lambda表达式的主体是MemberExpression类型
if (body.NodeType != ExpressionType.MemberInit)
throw new ArgumentException("Expression must be a member access", nameof(expression));
// 获取成员信息
var memberExpression = (MemberInitExpression)body;
foreach (var binding in memberExpression.Bindings)
{
MapMemberBinding(entity, binding);
}
return entity;
}
public static void MapMemberBinding<TEntity>(TEntity target, MemberBinding binding)
{
if (binding is MemberAssignment memberAssignment)
{
var property = typeof(TEntity).GetProperty(memberAssignment.Member.Name);
if (property != null && property.CanWrite)
{
if (ExpressionType.MemberAccess == memberAssignment.Expression.NodeType)
{
var constantValue = ((MemberExpression)memberAssignment.Expression).MemberToValue();
property.SetValue(target, constantValue);
}
else if (ExpressionType.Constant == memberAssignment.Expression.NodeType)
{
var constantExpression = (ConstantExpression)memberAssignment.Expression;
property.SetValue(target, constantExpression.Value);
}
}
}
}
}
public class ExpressionModifier : ExpressionVisitor
{
public ExpressionModifier(Expression newExpression, Expression oldExpression)
{
_newExpression = newExpression;
_oldExpression = oldExpression;
}
private readonly Expression _newExpression;
private readonly Expression _oldExpression;
public Expression Replace(Expression node)
{
return Visit(node == _oldExpression ? _newExpression : node);
}
public static Expression Replace(Expression node, Expression oldExpression, Expression newExpression)
{
return new ExpressionModifier(newExpression, oldExpression).Replace(node);
}
}
示例:
static void Main(string[] args)
{
Expression<Func<MyEntity, MyEntity>> expression = (s) => new MyEntity
{
Age = 25,
Name = "czj",
};
var entity = expression.MapToEntity<MyEntity>();
var str = System.Text.Json.JsonSerializer.Serialize(entity);
}
output:
{"Age":25,"Name":"czj"}