ASP.NET MVC中如何将MainVM的列表数据迁移至DescRecordsVM?
问题描述
我在MainVM视图模型中有两个列表,需要遍历这两个列表提取数据,统一添加到DescRecordsVM视图模型的Records列表中。具体映射规则如下:
- Attachments → Records:
Id→IddocumentName→DescriptiondocumentType→Type
- Emails → Records:
Id→IdEmailName→DescriptionEmailType→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库简化配置:
- 安装AutoMapper NuGet包:
Install-Package AutoMapper - 配置映射关系:
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();
- 控制器中使用:
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
相关产品推荐
相关产品推荐

