自学内容网 自学内容网

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"} 


原文地址:https://blog.csdn.net/czjnoe/article/details/142566714

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!