C# - 具有自定义类型转换的自动映射器
C# - Automapper with Custom Type Conversion
我正在尝试将请求对象映射到域,我可以阅读英语,但我在 automapper 文档中肯定找不到解决方案。
问题:
我如何根据 ContainedEvent 对象中的 EventType 属性将 ContainedEvent 对象从源映射到目标对象中的派生 class,因为 Event 是一个抽象 class。
因此,假设源对象中的 EventType == 1,则 Event 属性应转换为其派生的 classes 之一。我也不想映射空属性,但我处理了它。
这是请求对象
public class CreatePostRequest
{
public long EventTime { get; set; }
public List<IFormFile>? Pictures { get; set; }
public ContainedEvent Event { get; set; }
public virtual List<string>? Tags { get; set; }
}
public class ContainedEvent
{
public string Description { get; set; }
#nullable enable
public string? Requirements { get; set; }
public int? Slots { get; set; }
public double? EntrancePrice { get; set; }
public int EventType { get; set; }
}
这是域对象
public class Post
{
public int Id { get; set; }
public DateTime EventTime { get; set; }
public Location Location { get; set; }
public int LocationId { get; set; }
public AppUser User { get; set; }
public string UserId { get; set; }
public Event Event { get; set; }
public int EventId { get; set; }
#nullable enable
public IEnumerable<string>? Pictures { get; set; }
#nullable enable
public virtual List<PostTags>? Tags { get; set; }
}
public abstract class Event
{
public int Id { get; set; }
public string Description{ get; set; }
public string? Requirements { get; set; }
public Post? Post { get; set; }
}
这就是我所坚持的..
public class RequestToDomainProfile : Profile
{
public RequestToDomainProfile()
{
CreateMap<CreatePostRequest, Post>()
.ForAllMembers(opt => opt.Condition((src, dest, srcMember) => srcMember != null));
}
}
想法是将所有事件实现存储在context.Items中,并在映射中提供一个选择器。
没测试过,应该是这样的
当您创建地图时:
CreateMap<CreatePostRequest, Post>()
.ForMember(x => x.Event, opt => opt.MapFrom((src, dest, destMember, context) =>
{
if(src.Event.EventType == 1)
{
return context.Items["EventImplementation1"];
}
if(src.Event.EventType == 2)
{
return context.Items["EventImplementation2"];
}
// ...
}));
映射对象时:
Post p = _mapper.Map<CreatePostRequest, Post>(postRequest, opts =>
{
opts.Items["EventImplementation1"] = new YourFirstEventImplementation();
opts.Items["EventImplementation2"] = new YourSecondEventImplementation();
// ...
});
我正在尝试将请求对象映射到域,我可以阅读英语,但我在 automapper 文档中肯定找不到解决方案。
问题:
我如何根据 ContainedEvent 对象中的 EventType 属性将 ContainedEvent 对象从源映射到目标对象中的派生 class,因为 Event 是一个抽象 class。
因此,假设源对象中的 EventType == 1,则 Event 属性应转换为其派生的 classes 之一。我也不想映射空属性,但我处理了它。
这是请求对象
public class CreatePostRequest
{
public long EventTime { get; set; }
public List<IFormFile>? Pictures { get; set; }
public ContainedEvent Event { get; set; }
public virtual List<string>? Tags { get; set; }
}
public class ContainedEvent
{
public string Description { get; set; }
#nullable enable
public string? Requirements { get; set; }
public int? Slots { get; set; }
public double? EntrancePrice { get; set; }
public int EventType { get; set; }
}
这是域对象
public class Post
{
public int Id { get; set; }
public DateTime EventTime { get; set; }
public Location Location { get; set; }
public int LocationId { get; set; }
public AppUser User { get; set; }
public string UserId { get; set; }
public Event Event { get; set; }
public int EventId { get; set; }
#nullable enable
public IEnumerable<string>? Pictures { get; set; }
#nullable enable
public virtual List<PostTags>? Tags { get; set; }
}
public abstract class Event
{
public int Id { get; set; }
public string Description{ get; set; }
public string? Requirements { get; set; }
public Post? Post { get; set; }
}
这就是我所坚持的..
public class RequestToDomainProfile : Profile
{
public RequestToDomainProfile()
{
CreateMap<CreatePostRequest, Post>()
.ForAllMembers(opt => opt.Condition((src, dest, srcMember) => srcMember != null));
}
}
想法是将所有事件实现存储在context.Items中,并在映射中提供一个选择器。
没测试过,应该是这样的
当您创建地图时:
CreateMap<CreatePostRequest, Post>()
.ForMember(x => x.Event, opt => opt.MapFrom((src, dest, destMember, context) =>
{
if(src.Event.EventType == 1)
{
return context.Items["EventImplementation1"];
}
if(src.Event.EventType == 2)
{
return context.Items["EventImplementation2"];
}
// ...
}));
映射对象时:
Post p = _mapper.Map<CreatePostRequest, Post>(postRequest, opts =>
{
opts.Items["EventImplementation1"] = new YourFirstEventImplementation();
opts.Items["EventImplementation2"] = new YourSecondEventImplementation();
// ...
});