You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC中如何将MainVM的列表数据迁移至DescRecordsVM?

问题描述

我在MainVM视图模型中有两个列表,需要遍历这两个列表提取数据,统一添加到DescRecordsVM视图模型的Records列表中。具体映射规则如下:

  • Attachments → Records:
    • Id → Id
    • documentName → Description
    • documentType → Type
  • Emails → Records:
    • Id → Id
    • EmailName → Description
    • EmailType → Type

示例映射:

Attachments                         Records
ID = 5                             --> ID=5
documentName = "file.pdf"          --> Description = "file.pdf"
documentType="PDF"                 --> Type="PDF"

Emails                                 Records
ID = 7                               --> ID=7
EmailName = "Progress"               --> Description = "Progress"
EmailType="GMAIL"                    --> Type="GMAIL"

相关视图模型定义:

public class MainVM
{
    public List<AttachmentVM> Attachments { get; set; }
    public List<EmailVM> Emails{ get; set; }
}

public class AttachmentVM
{
    public Guid Id { get; set; }
    public string documentName { get; set; }
    public string documentType { get; set; }
}

public class EmailVM
{
    public Guid Id { get; set;  }
    public string EmailName{ get; set; }
    public string EmailType { get; set; }
}

目标视图模型:

public class DescRecordsVM
{
    public List<DescriptionVM> Records { get; set; }
}

public class DescriptionVM
{
    public Guid Id { get; set;  }
    public string Description{ get; set; }
    public string Type{ get; set; }
}

控制器代码(待补充逻辑):

public async Task<ActionResult> GetCommunications(long id )
{
    var vm = new ViewModels.MainVM();
    vm.Attachments = GetAttachments(id).ToList();
    // 注意:原代码存在错误,此处应调用GetEmails(id)而非GetAttachments(id)
    vm.Emails= GetAttachments(id).ToList();

    // 此处需遍历列表,将数据填充到DescRecordsVM的Records列表中

    return PartialView("view",Records);
}
实现方案

这个需求完全可以实现,下面提供几种常见的实现方式:

方式一:直接使用LINQ拼接转换

在控制器中直接通过LINQ将两个列表转换后合并,代码简洁直观:

public async Task<ActionResult> GetCommunications(long id )
{
    var vm = new ViewModels.MainVM();
    vm.Attachments = GetAttachments(id).ToList();
    // 修正原代码错误:获取Emails数据调用GetEmails方法
    vm.Emails = GetEmails(id).ToList();

    // 转换Attachments为DescriptionVM集合
    var attachmentRecords = vm.Attachments.Select(a => new DescriptionVM
    {
        Id = a.Id,
        Description = a.documentName,
        Type = a.documentType
    });

    // 转换Emails为DescriptionVM集合
    var emailRecords = vm.Emails.Select(e => new DescriptionVM
    {
        Id = e.Id,
        Description = e.EmailName,
        Type = e.EmailType
    });

    // 合并集合并封装到目标视图模型
    var recordsVM = new DescRecordsVM
    {
        Records = attachmentRecords.Concat(emailRecords).ToList()
    };

    return PartialView("view", recordsVM.Records);
}

方式二:封装转换方法(提升复用性)

如果需要在多个地方复用转换逻辑,可以把转换逻辑封装成静态方法或扩展方法:

扩展方法封装

public static class VMConverter
{
    public static DescriptionVM ToDescriptionVM(this AttachmentVM attachment)
    {
        return new DescriptionVM
        {
            Id = attachment.Id,
            Description = attachment.documentName,
            Type = attachment.documentType
        };
    }

    public static DescriptionVM ToDescriptionVM(this EmailVM email)
    {
        return new DescriptionVM
        {
            Id = email.Id,
            Description = email.EmailName,
            Type = email.EmailType
        };
    }
}

控制器中调用示例:

public async Task<ActionResult> GetCommunications(long id )
{
    var vm = new ViewModels.MainVM();
    vm.Attachments = GetAttachments(id).ToList();
    vm.Emails = GetEmails(id).ToList();

    var recordsVM = new DescRecordsVM
    {
        Records = vm.Attachments.Select(a => a.ToDescriptionVM())
                                .Concat(vm.Emails.Select(e => e.ToDescriptionVM()))
                                .ToList()
    };

    return PartialView("view", recordsVM.Records);
}

方式三:使用AutoMapper(适合复杂映射场景)

如果项目中有大量对象映射需求,可借助AutoMapper库简化配置:

  1. 安装AutoMapper NuGet包:Install-Package AutoMapper
  2. 配置映射关系:
var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<AttachmentVM, DescriptionVM>()
       .ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.documentName))
       .ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.documentType));

    cfg.CreateMap<EmailVM, DescriptionVM>()
       .ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.EmailName))
       .ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.EmailType));
});

IMapper mapper = config.CreateMapper();
  1. 控制器中使用:
public async Task<ActionResult> GetCommunications(long id )
{
    var vm = new ViewModels.MainVM();
    vm.Attachments = GetAttachments(id).ToList();
    vm.Emails = GetEmails(id).ToList();

    var attachmentRecords = mapper.Map<List<DescriptionVM>>(vm.Attachments);
    var emailRecords = mapper.Map<List<DescriptionVM>>(vm.Emails);

    var recordsVM = new DescRecordsVM
    {
        Records = attachmentRecords.Concat(emailRecords).ToList()
    };

    return PartialView("view", recordsVM.Records);
}

内容的提问来源于stack exchange,提问作者Michaelweston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 12:02:16