使用自动映射器自定义解析

本文关键字:自定义 映射 | 更新日期: 2023-09-27 18:27:54

我在应用程序中的一些层中有以下类结构(让我们称之为First):

public class Participant
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual User User { get; set; }
    public virtual Conversation Conversation { get; set; }
    public virtual ICollection<Message> Messages { get; set; }
}
public class User
{
    public int Id { get; set; }
    public string Login { get; set; }
    public virtual ICollection<Participant> Participants { get; set; }
}
public class Conversation
{
    public int Id { get; set; }
    public string Title { get; set; }
    public virtual ICollection<Participant> Participants { get; set; }
}

这里是另一层类结构(第二层):

public class Participant
{
    public int Id { get; set; }
    public string Name { get; set; }
    public User User { get; set; }
    public ICollection<Message> Messages { get; set; }
}
public class User
{
    public int Id { get; set; }
    public string Login { get; set; }
    public ICollection<Conversation> Conversations { get; set; }
}
public class Conversation
{
    public int Id { get; set; }
    public string Title { get; set; }
    public ICollection<Participant> Participants { get; set; }
}

除了一些细节之外,它们与基本相同,最重要的是第二个的User类可以直接访问Conversations,而第一个的User只能访问Participant的实例。

我必须将第一个用户的实例映射到第二个用户。由于简单的映射方式不起作用,我决定以下算法可能起作用:

当我们必须将第一用户映射到第二用户时,获取第一用户的所有参与者,获取每个参与者的对话并将其分配给第二用户。每个会话也需要转换,此会话的参与者集合也必须转换。我曾尝试在没有任何映射库的情况下进行此操作,但遇到了无限递归,因为为了转换First Conversation=>Second Conversation,我们必须转换参与者。要转换参与者,需要转换他们的对话等等。

据我所知,AutoMapper能够用无限递归处理简单的问题;然而,由于我的映射有点复杂,如果没有我的帮助,AM无法弄清楚如何映射类。

不幸的是,我不知道如何实现这样的映射。我看过这本指南,我想这正是我所需要的,但我根本不知道如何编写这个映射,这样它就可以正确地映射类,而不会像我以前的解决方案那样陷入无限递归。

如果有人能提供任何关于如何实现这种映射的想法,我会很高兴。

使用自动映射器自定义解析

您只需要通知AutoMapper如何映射不明显的属性,在本例中就是您的User类。为了便于阅读,我已经将"第二"层中的所有类重命名为xxxDTO。

Mapper.CreateMap<Conversation, ConversationDTO>();
Mapper.CreateMap<Participant, ParticipantDTO>();
Mapper.CreateMap<User, UserDTO>()
    .ForMember(dest => dest.Conversations,opt => opt.MapFrom(src => src.Participants.Select(p => p.Conversation)));
Mapper.CreateMap<Message, MessageDTO>();

如果一个用户有可能通过多个参与者链接到一个对话,那么您可以在Select(p => p.Conversation)之后包含一个.Distinct()