簡體   English   中英

用於映射數據的自動映射器配置

[英]Automapper configuration for grouping the data

我有以下型號

資源:

public class Opportunity
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public Guid QuotationId { get; set; }
    public int? QuotationNumber { get; set; }
    public int? QuotationVersionNumber { get; set; }
}

目標:

public class OpportunityDto
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public List<QuotationDto> Quotations { get; set; }
}

public class QuotationDto
{
    public Guid Id { get; set; }
    public int Number { get; set; }
    public int VersionNumber { get; set; }
}

我將從數據庫中獲取的數據與Opportunity模型保持一致,並且我的api公開了OpportunityDto模型。 因此,在我的自動映射器配置中,我有以下代碼:

services
    .AddSingleton(new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<OpportunityDto, Opportunity>().ReverseMap();
        cfg.CreateMap<QuotationDto, Quotation>().ReverseMap();
    }).CreateMapper())

我要實現的是唯一機會列表,每個機會都有一個嵌套成員,該成員將具有報價單。 如何使自動映射器執行此分組? 現在,從api返回的契機Dto的Quotations成員始終為空。

AutoMapper配置

您可以執行以下操作:

    public static void InitialiseMapper()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<IEnumerable<Opportunity>, OpportunityDto>()
                .ForMember(x => x.Id, x => x.MapFrom(y => y.FirstOrDefault().Id))
                .ForMember(x => x.Name, x => x.MapFrom(y => y.FirstOrDefault().Name))
                .ForMember(x => x.Quotations,
                    x => x.MapFrom(y => Mapper.Map<IEnumerable<Opportunity>, IEnumerable<QuotationDto>>(y).ToArray()))
                ;

            cfg.CreateMap<Opportunity, QuotationDto>()
                .ForMember(x => x.Id, x => x.MapFrom(y => y.QuotationId))
                .ForMember(x => x.Number, x => x.MapFrom(y => y.QuotationNumber))
                .ForMember(x => x.VersionNumber, x => x.MapFrom(y => y.QuotationVersionNumber))
                ;
        });
    }

測試

然后,它成功地知道如何進行映射,如以下測試所示:

    [TestMethod]
    public void TestMethod1()
    {
        var oppo1Guid = Guid.NewGuid();

        var opportunities = new List<Opportunity>
        {
            new Opportunity
            {
                Id = oppo1Guid,
                Name = "Mikeys Oppurtunity",
                QuotationId = Guid.NewGuid(),
                QuotationNumber = 169,
                QuotationVersionNumber = 80,
            },

            new Opportunity
            {
                Id = oppo1Guid,
                Name = "Mikeys Oppurtunity",
                QuotationId = Guid.NewGuid(),
                QuotationNumber = 170,
                QuotationVersionNumber = 20,
            }
        };

        var dtos = Mapper.Map<IEnumerable<Opportunity>, OpportunityDto>(opportunities);

        var json = JsonConvert.SerializeObject(dtos, Formatting.Indented);

        Console.WriteLine(json);
    }

輸出是

測試輸出

{
  "Id": "623c17df-f748-47a2-bc7e-35eb124dbfa3",
  "Name": "Mikeys Oppurtunity",
  "Quotations": [
    {
      "Id": "ad8b31c2-6157-4b7f-a1f2-9f8cfc1474b7",
      "Number": 169,
      "VersionNumber": 80
    },
    {
      "Id": "515aa560-6a5b-47da-a214-255d1815e153",
      "Number": 170,
      "VersionNumber": 20
    }
  ]
}

@Afflatus我會給你一個可以遵循的想法。 我假設您基於服務變量使用AspNetCore。

您可以創建這樣的擴展方法,以稍后在諸如services.RegisterMappingsWithAutomapper() ConfigurationServices上進行調用:

public static IServiceCollection RegisterMappingsWithAutomapper(this IServiceCollection services)
{
   var mapperConfig = AutoMapperHelper.InitializeAutoMapper();
   services.AddScoped<IMapper>(provider => new Mapper(mapperConfig));
   return services;
}

InitializeAutoMapper如下:

public static class AutoMapperHelper
{
    public static MapperConfiguration InitializeAutoMapper()
    {
        //Load here all your assemblies
        var allClasses = AllClasses.FromLoadedAssemblies();

        MapperConfiguration config = new MapperConfiguration(cfg =>
        {
            if (allClasses != null)
            { 
                //here normally I add another Profiles that I use with reflection, marking my DTOs with an interface
                cfg.AddProfile(new MappingModelsAndDtos(allClasses));
                cfg.AddProfile(new MyCustomProfile());
            }
        });

        return config;
    }
}

現在您需要實現Profile,在本例中為MyCustomProfile

public class ModelProfile : Profile
{
    public ModelProfile()
    {
        //put your source and destination here
        CreateMap<MySource, MyDestination>()
                .ConvertUsing<MySourceToMyDestination<MySource, MyDestination>>();
    }
}

您需要實現MySourceToMyDestination類。 貝婁是我在項目中如何使用它的代碼示例

public class ApplicationModel2ApplicationDto : ITypeConverter<ApplicationModel, ApplicationDto>
{
    public ApplicationDto Convert(ApplicationModel source, ApplicationDto destination, ResolutionContext context)
    {
        var mapper = context.Mapper;
        try
        {
            destination = new ApplicationDto
            { 
                ApplicationId = source.ApplicationId,
                ApplicationName = source.ApplicationName,
                Documents = mapper.Map<IEnumerable<DocumentDto>>(source.Documents),
                Tags = mapper.Map<IEnumerable<TagInfoDto>>(source.TagInfos)
            };
        }
        catch
        {
            return null;
        }

        return destination;
    }
}

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM