简体   繁体   English

自动映射器:对象列表中的Map属性

[英]Automapper: Map property in list of objects

I have a list of DTOs and want to map this list to a list of entites. 我有一个DTO列表,并且想要将此列表映射到实体列表。 The entity itself has one property which comes from another source. 实体本身具有一个属性,该属性来自另一来源。 Can I map this property to all items of the list with one map. 我可以使用一张地图将此属性映射到列表的所有项目。

My classes: 我的课程:

Entity: 实体:

public class Account
{
   public int Id {get;set;}
   public string Name {get;set;}
   public Guid ExternalId {get;set;}
}

DTO: DTO:

public class ExternalAccountDto
{
   public int Id {get;set;}
   public string Name {get;set;}
}

My Service: 我的服务:

public class AccountService
{
   public async Task AddExternalAccounts(Guid externalId, List<ExternalAccountDto> accounts)
   {            
        var entities = _mapper.Map(accounts);
        // TODO: Map 'externalId' to all entities
        // _mapper.Map(externalId, entities); // DOES NOT WORK!

        _context.Create(entities);
   }

}

Mapping 制图

public class AccountProfile: Profile
{
   public AccountProfile()
   {
      CreateMap<ExternalAccountDto, Account>();

      // TODO: CreateMap for Guid on every Account
   }
}

Can anyone give me some advice! 谁能给我一些建议!

You should use the AfterMap function to do some postprocessing on the mapped items. 您应该使用AfterMap函数对映射项进行一些后处理。

There are two ways to go about this. 有两种方法可以解决此问题。 One is using something statically defined in the mapping profile. 一种是使用映射配置文件中静态定义的内容。 But in your case, you have something that's dynamic at runtime, like the ExternalId . 但是在您的情况下,您会在运行时拥有动态的东西,例如ExternalId Doing the aftermap in your AccountService then makes perfect sense. 这样,在AccountService进行Aftermap就很有意义了。

I've found these kind of constructions very useful, especially when I want to consult other injected services for additional information. 我发现这类构造非常有用,尤其是当我想咨询其他注入服务以获取更多信息时。

   public void AddExternalAccounts(Guid externalId, List<ExternalAccountDto> accounts)
    {
        var entities = _mapper.Map<List<ExternalAccountDto>, List<Account>>(accounts, 
            options => options.AfterMap((source, destination) =>
                {
                    destination.ForEach(account => account.ExternalId = externalId);
                }));
    }

Two more cents regarding the AccountProfile class: 关于AccountProfile类的另外两个美分:
You can check upon creation of the mapping profile if the mapping profile is correct. 您可以在创建映射配置文件时检查映射配置文件是否正确。 This will save you a headache running into this problem later at runtime. 这将使您免于稍后在运行时遇到此问题。 You'll know immediately that there is a problem with the configuration. 您将立即知道配置存在问题。

 var config = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<MappingProfile>();
            cfg.AllowNullDestinationValues = false;
        });

        // Check that there are no issues with this configuration, which we'll encounter eventually at runtime.
        config.AssertConfigurationIsValid();

        _mapper = config.CreateMapper();

This also notified me that an .Ignore() on the ExternalId member of the Account class was required: 这也通知我,在Account类的ExternalId成员上需要一个.Ignore()

 CreateMap<ExternalAccountDto, Account>().ForMember(d => d.ExternalId, a => a.Ignore());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM