自动映射器,将单个目标属性映射为多个源属性的串联



我遇到一种情况,我需要根据某些条件将单个属性映射为多个源属性的组合。

目的地:

public class Email
{
    public Email() {
        EmailRecipient = new List<EmailRecipient>();
    }
    public string Subject{get; set;}
    public string Body {get; set;}
    public virtual ICollection<EmailRecipient> EmailRecipient { get; set; } 
}
public class EmailRecipient
{
    public int EmaiId { get; set; }
    public string RecipientEmailAddress { get; set; }
    public int RecipientEmailTypeId { get; set; }
    public virtual Email Email { get; set; }
}

源:

public class EmailViewModel
{
    public List<EmailRecipientViewModel> To { get; set; }
    public List<EmailRecipientViewModel> Cc { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
}
public class EmailRecipientViewModel
{
    public string RecipientEmailAddress { get; set; }
}

我要Mapper.Map<EmailViewModel,Email>()

在这里,我想将我的Email.EmailRecipient映射为EmailViewModel.ToEmailViewModel.Cc的组合。但是条件是,对于 To,Email.EmailRecipient.RecipientEmailTypeId 将为 1,对于抄送为 2

希望我的问题清楚。

实现此目的的一种可能方法是创建一个使用特定方法进行此转换的地图。地图创建方式为:

Mapper.CreateMap<EmailViewModel, Email>()
    .ForMember(e => e.EmailRecipient, opt => opt.MapFrom(v => JoinRecipients(v)));

JoinRecipients方法将执行转换本身的位置。一个简单的实现可以是这样的:

private ICollection<EmailRecipient> JoinRecipients(EmailViewModel viewModel) {
    List<EmailRecipient> result = new List<EmailRecipient>();
    foreach (var toRecipient in viewModel.To) {
        result.Add(new EmailRecipient {
            RecipientEmailTypeId = 1, 
            RecipientEmailAddress = toRecipient.RecipientEmailAddress
        });
    }
    foreach (var ccRecipient in viewModel.Cc) {
        result.Add(new EmailRecipient {
            RecipientEmailTypeId = 2,
            RecipientEmailAddress = ccRecipient.RecipientEmailAddress
        });
    }
    return result;
}

我是转换器的强烈反对者,主要是因为对于您项目中的其他人来说,在映射调用之后,事情会"像魔术一样"发生。

处理此问题的一种更简单的方法是将属性实现为将视图模型上的其他属性转换为所需格式的方法。例:

public class EmailViewModel
{
    public ICollection<EmailRecipient> EmailRecipient { 
        get {
             return To.Union(Cc);
        } 
    }
    public List<EmailRecipientViewModel> To { get; set; }
    public List<EmailRecipientViewModel> Cc { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
}

现在,自动映射器会自动从 EmailRecipient 属性映射到 EmailRecipient 属性,如果有人试图弄清楚它是如何发生的,他们只需要查看视图模型。

几年后编辑它:作为一个警告,以这种方式做事意味着每次你调用EmailRecipient时,你都会承担合并ToCc字段的o(n(任务。如果您只处理一封电子邮件,这很好,但是如果您重用视图模型并且有人将其与系统中的所有其他电子邮件放在一个循环中,这可能是一个巨大的性能问题。在这种情况下,我会选择公认的答案,以便您避开这个潜在的性能陷阱。

相关内容

  • 没有找到相关文章

最新更新