【问题标题】:use automapper to map single object into a list of objects使用 automapper 将单个对象映射到对象列表中
【发布时间】:2019-07-11 11:02:21
【问题描述】:

我的映射器中有以下行:

我正在尝试从一个模型(我有一个名为 Result 的属性)映射到一个模型,其中我有一个结果列表。

到目前为止,我有以下内容:

options.CreateMap<Contract.Dto.Result, List<Result>>(MemberList.Source).ConvertUsing<ResultConverter>();


internal class ResultConverter : ITypeConverter<Contract.Dto.Result, List<Result>>
    {
        public List<Result> Convert(Contract.Dto.Result source, List<Result> destination, ResolutionContext context)
        {
            destination.Add(context.Mapper.Map<Contract.Dto.Result, Result>(source));
            return destination;
        }
    }

但是,在调试时,ResultConverter 永远不会被命中。 有人对如何从单个对象映射到对象列表有任何解决方案吗?此对象列表中只会有一个对象,但其他约束阻止我修改模型。

【问题讨论】:

  • 如果列表中总是只有一个,为什么它是一个列表?您可以在 List 上将属性修改为 Result 吗?
  • 您使用的是哪个版本的自动映射器?
  • @lowry0031 不,我对更改模型无能为力。就是这样。
  • @andyb952 自动映射器版本 8.0.0
  • 另外,您是否在您的 IOC 容器中注册了转换器(如果使用)?我今天会看看这个,因为实际上只是使用了一个转换器并且遇到了同样的问题,但它可以正常工作。

标签: c# automapper


【解决方案1】:

我已经设法在我创建的一个非常小的类库中让它工作。我注意到可能会破坏您的代码的位:

没有提及您也在映射的任何地方 - 确保您已添加这两个映射

var config = new MapperConfiguration(options =>
{
    options.CreateMap<Contract.Dto.Result, List<Result>>(MemberList.Source).ConvertUsing<ResultConverter>();
    options.CreateMap<Contract.Dto.Result, Result>(MemberList.Source);
});

在您的转换器中,我将其更改为使用新的结果列表而不是目标

public List<Result> Convert(Contract.Dto.Result source, List<Result> destination, ResolutionContext context)
{
    var listOfResults = new List<Result>();
    var result = context.Mapper.Map<Contract.Dto.Result, Result>(source);
    listOfResults.Add(result);
    return listOfResults;
}

实际使用地图时,只要确保语法正确

var result = new Contract.Dto.Result();
var expected = mapper.Map<List<Result>>(result);

此外,如果使用国际奥委会,请确保您已注册转换者。下面是 Autofac 代码示例

 builder.RegisterType<ResultConverter>().AsSelf();
 builder.Register(context => new MapperConfiguration(options=>
 {
     options.CreateMap<Contract.Dto.Result, List<Result>>(MemberList.Source).ConvertUsing<ResultConverter>();
     options.CreateMap<Contract.Dto.Result, Result>(MemberList.Source);
 })).AsSelf().SingleInstance();


 builder.Register(c =>
 {
     //This resolves a new context that can be used later.
     var context = c.Resolve<IComponentContext>();
     var config = context.Resolve<MapperConfiguration>();
     return config.CreateMapper(context.Resolve);
 }).As<IMapper>().InstancePerLifetimeScope();

正如下面评论中提到的 OP,还要确保使用正确的类型,在这种情况下 List vs IList

在您的项目中尝试这些方法,希望能解决您的问题。如果不让我知道,我可以再看看。

【讨论】:

  • 谢谢,非常感谢您抽出宝贵时间。我有您在顶部提到的映射,并且您在底部提到的调用是正确的。我已经改变了我的转换以匹配你的建议,但不幸的是我没有改变。
  • 有什么方法可以在不使用转换类的情况下做到这一点?
  • 您是否在使用任何类型的 IOC,例如 autofac 或 ninject?不,我很确定转换器是做到这一点的唯一方法,无论如何它们绝对是最好的选择
  • 使用温莎城堡。我开始认为 Converter 类甚至没有被击中。例如在调试时,调试器从不进入代码
  • 没用过城堡windor,但我知道我在使用autofac时遇到了问题。我需要注册转换器。上面添加了autofac代码,确保已注册
【解决方案2】:

我从来没有使用过自动映射器。你可以试试这个,如果它有效,请告诉我:

        //Use this method.
        public void Map(object PreEqual, string PreEqProperty, object PostEqual, string PostEqProperty)
        {
            PreEqual.GetType().GetProperty(PreEqProperty).SetValue(PreEqual, PostEqual.GetType().GetProperty(PostEqProperty).GetValue(PostEqual, null), null);
        }

        //Use Map method somewhere you want, like this:
        //myRefObj is your source object and myRefProp is its property that you want to map to other objects.
        foreach(SomeType item in CollectionOfSomeType)
        {
             Map(item, "myRefProp", myRefObj, "myRefProp");
        }    

我认为它适用于原始类型。你能试试告诉我它是否有效吗?

【讨论】:

  • 感谢您的回复,但这只是一个自动映射器问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-16
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
相关资源
最近更新 更多