使用Auto Mapper自定义解析

时间:2015-12-24 10:19:50

标签: c# asp.net-mvc automapper

我在应用程序的某些层中有以下类结构(让我们称之为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; }
}

除了一些细节之外,它们几乎相同,最重要的是第二个用户类可以直接访问对话,而第一个用户只能访问实例参与者

我必须将第一个用户的实例映射到第二个用户。由于直接的映射方法不起作用,我认为以下算法可能有效:

当我们必须将第一个用户映射到第二个用户时,请抓住第一个用户的所有参与者,进行每个参与者的对话并将其分配给第二个用户。每个对话也需要进行转换,此对话的参与者集合也必须进行转换。我试图在没有任何映射库的情况下进行,但遇到无限递归,因为为了转换First Conversation =&gt;第二次对话,我们必须转换参与者。要转换参与者,需要转换他们的对话等。

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

不幸的是,我无法弄清楚如何实现这种映射。我查看了this guide,我想这就是我需要的东西,但我根本无法弄清楚如何编写这个映射,以便它能正确地映射类,而不是像我之前的解决方案那样进行无限递归。

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

1 个答案:

答案 0 :(得分:2)

您只需要告知AutoMapper如何映射非显而易见的属性,在本例中是您的User类。为了便于阅读,我已经重新命名了你的第二个&#34; layer to 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>();

如果用户可能会通过多个参与者与对话相关联,那么您可以在.Distinct()之后添加Select(p => p.Conversation)