【问题标题】:How to Map child list of object using AutoMapper如何使用 AutoMapper 映射对象的子列表
【发布时间】:2019-07-04 14:19:49
【问题描述】:

我有这两个表“用户”和“项目”。他们共享一对多的关系。 我得到的响应是一个列表,我想将此响应与我创建的 GetProjectManager 的 dto 映射,但我不确定如何在 automapper 配置文件中定义 CreateMap。 我从 ProjectManager 类型的 API 得到了这个响应:

项目经理:

[
  {
    "id": 1,
    "projectId": 1,
    "userId": 1,
    "project": {
      "id": 1,
      "projectName": "iDocument-FBAG",
      "plannedStartDate": "2019-07-03T00:00:00",
      "plannedEndDate": "2019-07-10T00:00:00",
      "actualStartDate": null,
      "actualEndDate": null,
      "projectDescription": "The client wants to enhance their existing .Net application. They have a WebForms application that uses DevExpress controls. They would like to start by implementing a chart type and creating a reusable report, also use that reusable report to implement some new reports.",
      "onProjects": [],
      "projectManagers": []
    },
    "user": {
      "firstName": "Abc",
      "lastName": "Efg",
      "isProjectManager": true,
      "registrationTime": "2019-06-28T19:28:55.8386138",
      "employees": null,
      "id": 1,
      "userName": "xyz@abc.com"
    }
  },
  {
    "id": 3,
    "projectId": 8,
    "userId": 1,
    "project": {
      "id": 8,
      "projectName": "Aquatrols-FBAG",
      "plannedStartDate": "2019-07-03T00:00:00",
      "plannedEndDate": "2019-07-10T00:00:00",
      "actualStartDate": null,
      "actualEndDate": null,
      "projectDescription": "The client wants to enhance their existing .Net application. They have a WebForms application that uses DevExpress controls. They would like to start by implementing a chart type and creating a reusable report, also use that reusable report to implement some new reports.",
      "onProjects": [],
      "projectManagers": []
    },
    "user": {
      "firstName": "Abc",
      "lastName": "Efg",
      "isProjectManager": true,
      "registrationTime": "2019-06-28T19:28:55.8386138",
      "employees": null,
      "id": 1,
      "userName": "xyz@abc.com"
    }
  }
]

我想将此响应与我创建的 Dto (GetProjectManager) 进行映射。

public class GetProjectManager
{
    public string ProjectManagerId { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public IList<GetProjectDto> GetProjects { get; set; }
}

public  class GetProjectDto
{
    public int ProjectId { get; set; }
    public string ProjectName { get; set; }
    public DateTime PlannedStartDate { get; set; }
    public DateTime PlannedEndDate { get; set; }
    public DateTime? ActualStartDate { get; set; }
    public DateTime? ActualEndDate { get; set; }
    public string ProjectDescription { get; set; }
}


public class ProjectManager
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Required]
    public int Id { get; set; }
    [Required]
    public int ProjectId { get; set; }
    [Required]
    public int UserId { get; set; }
    public Project Project { get; set; }
    public AppUsers User { get; set; }
}

【问题讨论】:

    标签: c# .net-core automapper


    【解决方案1】:

    首先,需要将响应json映射到类型

    namespace Response
    {
        public class ProjectManager
        {
            public int id { get; set; }
            public int projectId { get; set; }
            public int userId { get; set; }
            public Project project { get; set; }
            public User user { get; set; }
        }
    
        public class Project
        {
            public int id { get; set; }
            public string projectName { get; set; }
            public DateTime plannedStartDate { get; set; }
            public DateTime plannedEndDate { get; set; }
            public object actualStartDate { get; set; }
            public object actualEndDate { get; set; }
            public string projectDescription { get; set; }
            public object[] onProjects { get; set; }
            public object[] projectManagers { get; set; }
        }
    
        public class User
        {
            public string firstName { get; set; }
            public string lastName { get; set; }
            public bool isProjectManager { get; set; }
            public DateTime registrationTime { get; set; }
            public object employees { get; set; }
            public int id { get; set; }
            public string userName { get; set; }
        }
    }
    

    这是你的 dto

    namespace Dto
    {
        public class GetProjectManager
        {
            public string ProjectManagerId { get; set; }
            public string Email { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public IList<GetProjectDto> GetProjects { get; set; }
        }
    
        public class GetProjectDto
        {
            public int ProjectId { get; set; }
            public string ProjectName { get; set; }
            public DateTime PlannedStartDate { get; set; }
            public DateTime PlannedEndDate { get; set; }
            public DateTime? ActualStartDate { get; set; }
            public DateTime? ActualEndDate { get; set; }
            public string ProjectDescription { get; set; }
        }
    }
    

    然后,创建自动映射器配置文件以响应 dto map

    public class ResponseToDtoProfile : AutoMapper.Profile
    {
        public ResponseToDtoProfile()
        {
            CreateMap<Response.Project, Dto.GetProjectDto>()
                .ForMember(dst => dst.ProjectId, opt => opt.MapFrom(src => src.id))
                .ForMember(dst => dst.ProjectName, opt => opt.MapFrom(src => src.projectName))
                .ForMember(dst => dst.PlannedStartDate, opt => opt.MapFrom(src => src.plannedStartDate))
                .ForMember(dst => dst.PlannedEndDate, opt => opt.MapFrom(src => src.plannedEndDate))
                .ForMember(dst => dst.ActualStartDate, opt => opt.MapFrom(src => src.actualStartDate))
                .ForMember(dst => dst.ActualEndDate, opt => opt.MapFrom(src => src.actualEndDate))
                .ForMember(dst => dst.ProjectDescription, opt => opt.MapFrom(src => src.projectDescription));
    
            CreateMap<Response.ProjectManager, Dto.GetProjectManager>()
                .ForMember(dst => dst.ProjectManagerId, opt => opt.MapFrom(src => src.id))
                .ForMember(dst => dst.FirstName, opt => opt.MapFrom(src => src.user.firstName))
                .ForMember(dst => dst.LastName, opt => opt.MapFrom(src => src.user.lastName))
                .ForMember(dst => dst.GetProjects, opt => opt.MapFrom(src => src.project));
        }
    }
    

    为了投影 json 数组,让我们在集合上添加一个扩展方法

    public static class ExtensionsHelper
    {
        public static List<TProjection> ProjectAsCollection<TProjection>(this IEnumerable<object> items) where TProjection : class
        {
            //var adapter = <Create Type Adapter>
            return adapter.Adapt<List<TProjection>>(items);
        }
    }
    

    最后,您可以将 json 数组投影到您的 dto。

    static void Main(string[] args)
    {
        string jsonString = "[ { \"id\": 1, \"projectId\": 1, \"userId\": 1, \"project\": { \"id\": 1, \"projectName\": \"iDocument-FBAG\", \"plannedStartDate\": \"2019-07-03T00:00:00\", \"plannedEndDate\": \"2019-07-10T00:00:00\", \"actualStartDate\": null, \"actualEndDate\": null, \"projectDescription\": \"The client wants to enhance their existing .Net application. They have a WebForms application that uses DevExpress controls. They would like to start by implementing a chart type and creating a reusable report, also use that reusable report to implement some new reports.\", \"onProjects\": [], \"projectManagers\": [] }, \"user\": { \"firstName\": \"Abc\", \"lastName\": \"Efg\", \"isProjectManager\": true, \"registrationTime\": \"2019-06-28T19:28:55.8386138\", \"employees\": null, \"id\": 1, \"userName\": \"xyz@abc.com\" } }, { \"id\": 3, \"projectId\": 8, \"userId\": 1, \"project\": { \"id\": 8, \"projectName\": \"Aquatrols-FBAG\", \"plannedStartDate\": \"2019-07-03T00:00:00\", \"plannedEndDate\": \"2019-07-10T00:00:00\", \"actualStartDate\": null, \"actualEndDate\": null, \"projectDescription\": \"The client wants to enhance their existing .Net application. They have a WebForms application that uses DevExpress controls. They would like to start by implementing a chart type and creating a reusable report, also use that reusable report to implement some new reports.\", \"onProjects\": [], \"projectManagers\": [] }, \"user\": { \"firstName\": \"Abc\", \"lastName\": \"Efg\", \"isProjectManager\": true, \"registrationTime\": \"2019-06-28T19:28:55.8386138\", \"employees\": null, \"id\": 1, \"userName\": \"xyz@abc.com\" } } ]";
        var rootObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Response.ProjectManager[]>(jsonString).ToList().ProjectAsCollection<Dto.GetProjectManager>();
    }
    

    我希望能回答这个问题。

    【讨论】:

    • 非常感谢您的快速回复:)
    • 我不得不在 AutoMapper 配置文件中使用 CreateMap,它解决了我的问题。
    • 嗨@SahidulHussain,如果这个或任何答案解决了您的问题,请点击复选标记考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。
    【解决方案2】:
    I had to play around with the CreateMap in the AutoMapper profile and it solved my problem. 
    

    这就是我定义映射的方式。

    CreateMap<ProjectManager, GetProjectDto>()
                                .ForMember(dst => dst.ProjectId, opt => opt.MapFrom(src => src.Project.Id))
                                .ForMember(dst => dst.ProjectName, opt => opt.MapFrom(src => src.Project.ProjectName))
                                .ForMember(dst => dst.PlannedStartDate, opt => opt.MapFrom(src => src.Project.PlannedStartDate))
                                .ForMember(dst => dst.PlannedEndDate, opt => opt.MapFrom(src => src.Project.PlannedEndDate))
                                .ForMember(dst => dst.ActualStartDate, opt => opt.MapFrom(src => src.Project.ActualStartDate))
                                .ForMember(dst => dst.ActualEndDate, opt => opt.MapFrom(src => src.Project.ActualEndDate))
                                .ForMember(dst => dst.ProjectDescription, opt => opt.MapFrom(src => src.Project.ProjectDescription));
    
                    CreateMap<List<ProjectManager>, GetProjectManager>()
                                   .ForMember(dst => dst.ProjectManagerId,
                                                opt => opt.MapFrom(src =>
                                                                    src.FirstOrDefault().UserId))
                                   .ForMember(dst => dst.FirstName,
                                                opt => opt.MapFrom(src =>
                                                                    src.FirstOrDefault().User.FirstName))
                                   .ForMember(dst => dst.LastName,
                                                opt => opt.MapFrom(src =>
                                                                    src.FirstOrDefault().User.LastName))
                                   .ForMember(dst => dst.Email,
                                                opt => opt.MapFrom(src =>
                                                                    src.FirstOrDefault().User.Email))
                                    .ForMember(dst => dst.GetProjects,
                                                 opt => opt.MapFrom(src =>
                                                                    src.Select(x => new ProjectManager
                                                                    {
                                                                        Project = x.Project
                                                                    })));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-16
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 2022-11-16
      • 2013-05-09
      • 2011-08-01
      相关资源
      最近更新 更多