当前位置: 首页 > article >正文

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


http://www.kler.cn/a/320857.html

相关文章:

  • IP 地址与蜜罐技术
  • C++的标准和C++的编译版本
  • Ruby语言的软件开发工具
  • mysql中查询json的技巧
  • 【QT-QTableView实现鼠标悬浮(hover)行高亮显示+并设置表格样式】
  • Springboot SAP Docker 镜像打包问题
  • javascript中new操作符的工作原理
  • 使用lodash库实现防抖和节流
  • Easy Excel从入门到精通!!!
  • pg入门11-pg中的publications是什么
  • SpringBoot整合Lombok插件与使用说明
  • 微信小程序showLoading ,showToast ,hideLoading连续调用出现showLoading 不关闭的情况记录
  • SpringDoc OpenApi学习笔记
  • GO Ants 学习
  • C++——将数组a[5]={-1,2,9,-5,7}中小于0的元素置成0。并将其结果输出(要求:用数组名作为函数的参数来实现)
  • C++游戏
  • Linux部署python web项目Flask + gunicorn + nginx
  • 《经典图论算法》约翰逊算法(Johnson)
  • 前端插件开发用什么技术比较好,用来程序自动化下载
  • TypeScript 设计模式之【单例模式】
  • [每日一练]修复表中的名字
  • Dependency Check:一款针对应用程序依赖组件的安全检测工具
  • ACM MM24 | Hi3D: 3D生成领域再突破!新视角生成和高分辨率生成双SOTA(复旦智象等)
  • Java 编码系列:异常处理与自定义异常
  • 一些广泛认可的编程工具,在不同的方面帮助我们提升效率
  • 使用cmd命令窗口操作mongodb