C# 映射递归对象

Posted lee576

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 映射递归对象相关的知识,希望对你有一定的参考价值。

首先映射对象很简单,同名的可以使用表达树进行一个深拷贝


    /// <summary>
    /// 高性能深拷贝,使用表达式树
    /// </summary>
    /// <typeparam name="TIn"></typeparam>
    /// <typeparam name="TOut"></typeparam>
    public static class DeepClone<TIn, TOut>
    
        private static readonly Func<TIn, TOut> cache = GetFunc();
        private static Func<TIn, TOut> GetFunc()
        
            ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
            List<MemberBinding> memberBindingList = new List<MemberBinding>();

            foreach (var item in typeof(TOut).GetProperties())
            
                if (!item.CanWrite) continue;
                MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));
                MemberBinding memberBinding = Expression.Bind(item, property);
                memberBindingList.Add(memberBinding);
            

            MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());
            Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[]  parameterExpression );

            return lambda.Compile();
        

        public static TOut Trans(TIn tIn)
        
            return cache(tIn);
        
    

递归就复杂一些,但是我这里有个偷懒的现成的方案,使用 AutoMapper + AutoMapper.Collection

关于 AutoMapper.Collection 使用nuget 自行安装, 下面有两个递归结构的类

    public class DepartmentEntity : BasicWithDescr
    
        /// <summary>
        /// 父级编码 
        ///</summary>
        public string ParentId  get; set; 
        /// <summary>
        /// 父级名称 
        ///</summary>
        public string ParentDescr  get; set; 
        /// <summary>
        /// 父级编码 
        ///</summary>
        public string Id  get; set; 
        /// <summary>
        /// 父级名称 
        ///</summary>
        public string Descr  get; set; 
        /// <summary>
        /// 子节点集合
        ///</summary>
        public List<DepartmentEntity> Child  get; set; 
    

另外一个树结构实体

    public class VueSelectTreeVM
    
        public string id  set; get; 
        public string ParentId  set; get; 
        public string label  set; get; 
        public List<VueSelectTreeVM> children  set; get; 
    

下面把 List<DepartmentEntity> 映射到 List<VueSelectTreeVM>,using 这两个命名空间

using AutoMapper;
using AutoMapper.EquivalencyExpression;
                var result = new List<VueSelectTreeVM>();
                //使用AutoMapper.Collection  扩展库进行递归映射到视图对象
                var config = new MapperConfiguration(ctx => ctx.CreateMap<DepartmentEntity, VueSelectTreeVM>().EqualityComparison((src, dest) => src.Id == dest.id)
                .ForMember(dest => dest.label, opt => opt.MapFrom(src => src.Descr))
                .ForMember(dest => dest.children, opts => opts.MapFrom(src => src.Child)));
                var mapper = config.CreateMapper();
                result = mapper.Map<List<VueSelectTreeVM>>(app.TreeOnCache());

其中 app.TreeOnCache() 返回的结果是 List<DepartmentEntity>

以上是关于C# 映射递归对象的主要内容,如果未能解决你的问题,请参考以下文章

C# 映射递归对象

C# - 递归/反射属性值

如何从 Freemarker 中的模板数据映射对象递归打印数据?

使用 RKObjectMapping 进行递归映射?

使用映射库将嵌套对象映射到 C# 中的自定义对象

关系对象映射 c#