【问题标题】:AutoMapper Object Collections not mappingAutoMapper 对象集合不映射
【发布时间】:2019-01-10 07:00:21
【问题描述】:

我正在尝试将具有相同布局的类映射到我要映射到的类。一切顺利,除非我尝试映射对象集合。例如,当我尝试映射源类中定义的这个属性时:

[System.Xml.Serialization.XmlElementAttribute("trust", typeof(Trust))]
[System.Xml.Serialization.XmlElementAttribute("valuation", typeof(Valuation))]
[System.Xml.Serialization.XmlElementAttribute("waiver_of_premium_ind", typeof(YesNo))]
[System.Xml.Serialization.XmlElementAttribute("written_under_trust_ind", typeof(YesNo), IsNullable = true)]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
public object[] Items
{
    get { return this.itemsField; }
    set { this.itemsField = value; }
}

我发现它没有映射,而是保留在与源对象相同的命名空间中,即使它是目标对象中的一个集合。

不知道你对这件事有什么想法吗?

编辑: 通过示例获得更多信息 - 源类:

namespace Namespace1
{
public class Person
{
    public int PersonID { get; set; }
    public List<Arm> Arms { get; set; }

    [System.Xml.Serialization.XmlElementAttribute("_arms", typeof(Arm))]
    [System.Xml.Serialization.XmlElementAttribute("_hand", typeof(Hand))]
    public object[] Items { get; set; }
}

public class Arm
{
    public Hand Hand { get; set; }
}

public class Hand
{
    public int HandID { get; set; }
    public string HandSide { get; set; }
    public List<Fingers> Fingers { get; set; }
}

public class Fingers
{
    public int FingerNumber { get; set; }
}
}

目标类别:

namespace Namespace2
{
public class Person
{
    public int PersonID { get; set; }
    public List<Arm> Arms { get; set; }

    [System.Xml.Serialization.XmlElementAttribute("_arms", typeof(Arm))]
    [System.Xml.Serialization.XmlElementAttribute("_hand", typeof(Hand))]
    public object[] Items { get; set; }
}

public class Arm
{
    public Hand Hand { get; set; }
}

public class Hand
{
    public int HandID { get; set; }
    public string HandSide { get; set; }
    public List<Fingers> Fingers { get; set; }
}

public class Fingers
{
    public int FingerNumber { get; set; }
}
}

映射两种类型和两个命名空间内所有嵌套类型的代码:

public static void CreateMappings(string nsFrom, string nsTo, Type typeFrom)
{
    Assembly assembly = Assembly.GetAssembly(typeFrom);
    var TypesInNamespace = assembly.GetTypes().Where(type => type.Namespace == nsFrom);
    foreach (var sourceType in TypesInNamespace)
    {
        Type destinationType = Type.GetType(sourceType.FullName.Replace(nsFrom, nsTo));
        Mapper.CreateMap(sourceType, destinationType);
    }
}

然后我从 Namespace1 创建我的 person 对象并使用上面的函数创建映射,如下所示:

CreateMappings("Namespace1", "Namespace2", typeof(Namespace1.Person));

之后我像这样调用地图函数:

var result = Mapper.Map<Namespace2.Person>(person);

这很好地映射了 Person 类的所有属性,除了 Items 对象数组。它传输对象,但它们仍然属于 Namespace1 而不是 Namespace2 命名空间。

可以在监视窗口中找到问题的图像here

喜欢here的可以下载控制台应用

感谢您提供的任何帮助。 M

【问题讨论】:

    标签: c# automapper


    【解决方案1】:

    我知道这真的很旧,但我确实找到了答案(至少对于 AutoMapper 的最新版本(此答案时为 8.0)。您需要为 Person 编写一个自定义 ITypeConverter 来执行对象[]。

    在我的例子中,我有一个像这样的对象(xml 属性被删除):

    namespace bob {
        public class sally 
        {
            public bob.MyEnum[] SomeVarName {get;set;}
            public object[] SomeValueVar {get;set;}
        }
    }
    
    namespace martin {
        public class sally 
        {
            public martin.MyEnum[] SomeVarName {get;set;}
            public object[] SomeValueVar {get;set;}
        }
    }
    

    自定义类型转换器如下所示:

    public class LocationTypeResolver : ITypeConverter<bob.sally,martin.sally>
    {
        public martin.sally Convert(bob.sally source, martin.sally destination, ResolutionContext context)
        {
            var retVal = new martin.sally
                         {
                             SomeValueVar = new object[source.SomeVarName.Length],
                             SomeVarName  = new martin.MyEnum[source.SomeVarName.Length]
                         };
    
            for (int i = 0; i < source.Items.Length; i++)
            {
                retVal.SomeVarName[i] = (martin.MyEnum)Enum.Parse(typeof(martin.MyEnum), source.SomeVarName[i].ToString());
    
                switch (source.ItemsElementName[i])
                {
                    //map any custom types
                    default:
                        retVal.SomeValueVar[i] = source.SomeValueVar[i]
                }
            }
    
            return retVal;
        }
    }
    

    【讨论】:

      【解决方案2】:

      我尝试了以下方法,它似乎有效;

      public class Tester
      {
          public void Test()
          {
              AutoMapper.Mapper.CreateMap<FirstObject, SecondObject>();
      
      
              FirstObject t = new FirstObject();
              t.Items = new object[] { new Item() { Id = 1 }, new Item() { Id = 2 } };
      
              SecondObject result = AutoMapper.Mapper.Map<SecondObject>(t);
          }
      }
      
      
      
      public class FirstObject
      {
          public object[] Items { get; set; }
      
      }
      
      public class SecondObject
      {
          public object[] Items { get; set; }
      }
      
      public class Item
      {
          public int Id { get; set; }
      }
      

      【讨论】:

      • 您好,感谢您查看此内容。我认为关键的区别在于这两种类型属于不同的命名空间。所以我发现当(且仅当)涉及对象集合时,它们不会映射到目标对象名称空间。我在link 上整理了一个简单的例子,希望能说明这一点——它是一个带有两个单独的类定义的控制台应用程序。它显示我正在映射两个对象中的各种类型,并且我正在动态地这样做。感谢您提供任何进一步的帮助。米
      • 请参阅我对上述问题的更新说明。再次感谢您提供的任何帮助。米
      猜你喜欢
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      • 2018-03-12
      • 2015-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多