【问题标题】:how to map using Automapper如何使用 Automapper 进行映射
【发布时间】:2020-12-02 15:07:53
【问题描述】:

我需要映射两个对象。要求是火车预订详细信息,其中包含行程和回程详细信息。

public class ReservationSource
{
    public string ReservationNumber{get;set;} 
    public TravelS towardsTravelS{get;set;}
    public TravelS returnTravelS{get;set;}
}

这是ReservationSource 类中的类,用于捕获往返旅程的详细信息。

public class TravelS
{
   public string travelId{get;set;}
   public ICollection<JourneyS> Journeys{get;set;}
}

上面是预留源对象。此源需要映射到目标对象。目标对象如下所示。

public class ReservationDestination
{
    public string ReservationNumber{get;set;}
    public TravelD towardsTravelD{get;set;}
    public TravelD returnTravelD{get;set;}

}

public class TravelD
{
    public string travelId{get;set;}
    public ICollection<JourneyD> Journeys{get;set;}
}
public class JourneyD
{
    public string JourneyId{get;set;}
}
public class JourneyS
{
    public string JourneyId{get;set;}
}

这是我的目标对象。在这里,我想将我的源映射到目的地。我如何定义映射配置和映射。

var config = new mappingConfiguration(cfg=>
{
cfg.CreateMap<ReservationSource,ReservationDestination>()
});

Imapper map = config.CreateMapper();

这部分代码仅将reservationNumber 映射到目标对象。有人可以帮我映射所有对象。即towardsTravelStowardsTravelDreturnTravelSreturnTravelD

.net 核心版本:3.1

【问题讨论】:

    标签: c# .net asp.net-mvc asp.net-core automapper


    【解决方案1】:

    首先你忘了提到这一点,但我假设还有一个类 TravelS 看起来像这样:

    public class TravelS
    {
        public string TravelId { get; set; }
    }
    

    您的配置中缺少一些内容。目前 AutoMapper 不知道它必须映射具有不同名称的属性(TowardsTravelS => TowardsTravelD 等)所以我们也必须定义这些:

    cfg.CreateMap<ReservationSource, ReservationDestination>()
        .ForMember(dest => dest.ReturnTravelD, opt => opt.MapFrom(src => src.ReturnTravelS))
        .ForMember(dest => dest.TowardsTravelD, opt => opt.MapFrom(src => src.TowardsTravelS));
    

    这里我们告诉 AutoMapper 需要映射这些不同名称的属性。

    其次,TravelSTravelD 是不同的类,因此我们还需要配置它们以进行映射:

    cfg.CreateMap<TravelS, TravelD>();
    

    所以我们现在有这样的东西:

    var config = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<ReservationSource, ReservationDestination>()
          .ForMember(dest => dest.ReturnTravelD, opt => opt.MapFrom(src => src.ReturnTravelS))
          .ForMember(dest => dest.TowardsTravelD, opt => opt.MapFrom(src => src.TowardsTravelS));
        cfg.CreateMap<TravelS, TravelD>();
    });
    
    var mapper = config.CreateMapper();
    
    var source = new ReservationSource
    {
        ReservationNumber = "9821",
        ReturnTravelS = new TravelS
        {
          TravelId = "1"
        },
        TowardsTravelS = new TravelS
        {
          TravelId = "2"
        }
    };
    
    var destination = mapper.Map<ReservationDestination>(source);
    
    Console.WriteLine(JsonSerializer.Serialize(destination));
    

    输出:

    {"ReservationNumber":"9821","TowardsTravelD":{"TravelId":"2"},"ReturnTravelD":{"TravelId":"1"}}
    

    在这里亲自尝试一下:https://dotnetfiddle.net/FfccVR

    【讨论】:

    • 感谢它的工作。如果我想更新一些信息,比如火车的实时信息(实际到达/出发)(想象我从不同的来源得到这个),我可以更新我们通过 automapper 映射的数据吗?假设我有一个旅行集合/列表,并且我需要来自不同 api 的旅行类中的少量信息,并且在映射所有其他字段之后,我想更新一些属性。注意:集合/列表在内部类中
    • 你必须找到合适的对象来更新自己。但是您可以映射到现有对象(存在Map&lt;TSource, TDestination&gt;(TSource source, TDestination) 重载)。这意味着您可以链接来自多个源对象的地图(或稍后更新目标对象)。只需确保您用作源的每种类型都需要配置到目标类型的映射。祝项目顺利!
    【解决方案2】:

    在启动时将其添加到您的服务中:

    它可重复使用且更清洁

     public void ConfigureServices(IServiceCollection services)
    {
                services.AddAutoMapper(Assembly.GetExecutingAssembly());
    }
    

    在你的项目中添加这些接口和类

    public interface IMapFrom<T>
    {
            void Mapping(Profile profile) => profile.CreateMap(typeof(T), GetType());
    }
    
    using AutoMapper;
    using System;
    using System.Linq;
    using System.Reflection;
    
        public class MappingProfile : Profile
        {
            public MappingProfile()
            {
                ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly());
            }
    
            private void ApplyMappingsFromAssembly(Assembly assembly)
            {
                    var types = assembly.GetExportedTypes()
                    .Where(t => t.GetInterfaces()
                    .Any(i =>i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>)))
                    .ToList();
    
                foreach (var type in types)
                {
                    var instance = Activator.CreateInstance(type);
    
                    var methodInfo = type.GetMethod("Mapping")
                        ?? type.GetInterface("IMapFrom`1").GetMethod("Mapping");
    
                    methodInfo?.Invoke(instance, new object[] { this });
    
                }
            }
        }
    

    你的源模型是这样的(将 ReservationSource 映射到 ReservationSource):

     public class ReservationSource : IMapFrom<ReservationSource>
        {
    
            public string Name { get; set; }
    
            public string City { get; set; }
    
            public void Mapping(Profile profile)
            {
                profile.CreateMap<ReservationSource,ReservationDestination>()
                           .ForMember(dest => dest.ReturnTravelD, opt => opt.MapFrom(src => src.ReturnTravelS))
                           .ForMember(dest => dest.TowardsTravelD, opt => opt.MapFrom(src => src.TowardsTravelS));
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2016-04-13
      • 2013-03-11
      • 1970-01-01
      • 2012-11-09
      • 2017-02-14
      • 2012-07-01
      • 2023-04-02
      • 2022-01-18
      相关资源
      最近更新 更多