C#AutoMapper将展平对象映射到复杂对象列表

时间:2019-07-25 13:47:56

标签: c# asp.net .net automapper

Automapper我正在尝试将简单对象“ Source”映射到复杂对象“ Dest”

在这里我想将字段F2,F3,F4映射到复杂对象List <DestChild1>

示例

来源对象:

 public class Source 
    {
       public int F1;
       public int F2;
       public int F3;
       public int F4;
    }

    Complex Object structure:

    public class Dest
    {
          public int F1;
          public List<DestChild1>  DestChild1;
     }

    public class DestChild1  
    {
       public int F2;
       public int F3;
       public DestChild2  DestChild2;
    }

    public class DestChild2  
    {
       public int F4;
    }


I was able to manually map it

Dest result = new Dest(){
F1 = source.F1,
DestChild1 =  new List<DestChild1>() {
 new DestChild1(){
   F2 = source.F2,
   F3 = source.F3,
   DestChild2 = new DestChild2() { F4 = source.F4 }
  }
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

提供的是使用反射完成您要寻找的内容的基本示例。但是,正如我在上面的评论中提到的那样,一旦开始添加集合,它将变得更加复杂,除非您有一种方法知道在子对象中应该将什么分组在一起。

using System;
using System.Linq;
using System.Reflection;

namespace ObjectMapper
{
    public class Program
    {
        static void Main(string[] args)
        {
            Source source = new Source();
            source.F1 = 1;
            source.F2 = 2;
            source.F3 = 3;
            source.F4 = 4;

            Dest result = new Dest()
            {
                F1 = source.F1,
                DestChild1 = 
                     new DestChild1()
                     {
                         F2 = source.F2,
                         F3 = source.F3,
                         DestChild2 = new DestChild2() { F4 = source.F4 }
                     }
            };


            Dest dest2 = new Dest();
            SetValues(ref source, ref dest2);

            Console.WriteLine("Set breakpoint here so you can inspect object");
        }

        public static void SetValues<T1,T2>(ref T1 sourceObject, ref T2 destObject)
        {
            PropertyInfo[] pi = sourceObject.GetType().GetProperties();
            //Loop through each sourceObject Property
            foreach (PropertyInfo sourcePI in sourceObject.GetType().GetProperties())
            {
                //Loop through each destination property to find matching destination property
                foreach (PropertyInfo destPI in destObject.GetType().GetProperties())
                {
                    //Within each destination property, look for attribute decorator that says this is the object we want to pair
                    foreach (SourceAttribute sourcePropertyToMatch in destPI.GetCustomAttributes(typeof(SourceAttribute), true).Cast<SourceAttribute>())
                    {
                        //If the source object property we are on matches the attribute decorator of the destination object property, set its value
                        if (String.Compare(sourcePI.Name, sourcePropertyToMatch.Name, true) == 0 || String.Compare(sourcePI.Name, destPI.Name, true)==0)
                        {
                            //Get value from our source object that so we can set it to our destination value
                            object val = sourcePI.GetValue(sourceObject);

                            //Avoid null reference exception should we somehow be attempting to assign a null value to a non-nullable type
                            if (val != null)
                            {
                                destPI.SetValue(destObject, val, null);
                            }
                            break;
                        }
                    }

                    //if we get here, there was no source attribute matched. check if it is one of our subobjects and dive into it
                    var destObjectSubObject = destPI.GetValue(destObject);
                    if (destObjectSubObject is DestinationBaseObject)
                    {
                        MethodInfo setValMethodDef = typeof(Program).GetMethod("SetValues");
                        MethodInfo setValMethod = setValMethodDef.MakeGenericMethod(new Type[] { sourceObject.GetType(), destObjectSubObject.GetType() });
                        var parameters = new object[] { sourceObject, destObjectSubObject };
                        setValMethod.Invoke(null, parameters);

                        destPI.SetValue(destObject, destObjectSubObject);
                    }
                }
            }
        }
    }

    public class Source
    {
        public int F1 { get; set; }
        public int F2 { get; set; }
        public int F3 { get; set; }
        public int F4 { get; set; }
    }

    public abstract class DestinationBaseObject { }
    public class Dest: DestinationBaseObject
    {
        public Dest()
        {
            DestChild1 = new DestChild1();
        }
        [SourceAttribute("F1")]
        public int F1 { get; set; }
        public DestChild1 DestChild1 { get; set; }
    }

    public class DestChild1 : DestinationBaseObject
    {
        public DestChild1()
        {
            DestChild2 = new DestChild2();
        }
        [SourceAttribute("F2")]
        public int F2 { get; set; }
        [SourceAttribute("F3")]
        public int F3 { get; set; }
        public DestChild2 DestChild2 { get; set; }
    }

    public class DestChild2 : DestinationBaseObject
    {
        [SourceAttribute("F4")]
        public int F4 { get; set; }
    }
    public class SourceAttribute : Attribute
    {

        public SourceAttribute(string name)
        {
            Name = name;
        }
        public String Name { get; private set; }
    }
}
相关问题