C# 跨通用DTO类重用通用映射代码

C# 跨通用DTO类重用通用映射代码,c#,code-reuse,C#,Code Reuse,我有两个DTO类,它们有多个公共属性,我试图避免在编写实体到DTO转换的映射代码时重复自己的操作,我想知道如何实现这一点,我觉得我可能需要使用Func或操作委托来实现这一点。例如,我有两个班,分别是StudentDTO和EmployeeDTO: public class StudentDTO : PersonDTO { public int CourseId { get; set; } //other properties } public class EmployeeDTO

我有两个DTO类,它们有多个公共属性,我试图避免在编写实体到DTO转换的映射代码时重复自己的操作,我想知道如何实现这一点,我觉得我可能需要使用
Func
操作
委托来实现这一点。例如,我有两个班,分别是
StudentDTO
EmployeeDTO

public class StudentDTO : PersonDTO
{
    public int CourseId { get; set; }
    //other properties
}

public class EmployeeDTO : PersonDTO
{
    public int OccupationId { get; set; }
    //other properties
}
两者都是从PersonDTO自然继承的:

public class PersonDTO
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string FamilyName { get; set; }
    public int Age { get; set; }
}

如何重用映射公共属性的映射代码?谢谢。

使用图书馆。。这就是他们在那里的目的

在Automapper中,上述映射变得非常简单:

Mapper.CreateMap<EmployeeDTO, StudentDTO>();
Mapper.CreateMap<StudentDTO, EmployeeDTO>();
Mapper.CreateMap();
CreateMap();
…然后,当您要映射时:

var studentInstance = ...; // go get student instance
var employee = Mapper.Map<Employee>(studentInstance);
var studentInstance=…;//获取学生实例
var employee=Mapper.Map(studentInstance);

您可能可以这样做(非常基本,但不优雅): (注意实体可以是数据读取器、数据集等)

公共类实体
{
公共字符串名{get;set;}
公共字符串FamilyName{get;set;}
public int CourseId{get;set;}
公共int职业ID{get;set;}
}
基于公共类的
{
}
公共类人物:BaseDto
{
公共字符串名{get;set;}
公共字符串FamilyName{get;set;}
公共静态void映射(实体实体,PersonDto PersonDto)
{
personDto.FirstName=entity.FirstName;
personDto.FamilyName=entity.FamilyName;
}
}
公立班学生收件人:PersonDto
{
public int CourseId{get;set;}
公共静态学生地图(实体)
{
var studentDto=新studentDto{CourseId=entity.CourseId};
//…如果您愿意,可以将map呼叫给PersonDto
把学生送回学校;
}
}
公共类雇员收件人:PersonDto
{
公共int职业ID{get;set;}
公共静态EmployeeDto映射(实体)
{
var employeeDto=new employeeDto(){ocportationid=entity.ocportationid};
//…如果您愿意,可以将map呼叫给PersonDto
让员工返回工作岗位;
}
}
公共类映射器
其中TDto:BaseDto
{
私人TDO;
私有只读实体_实体;
公共映射器(实体)
{
_实体=实体;
}
公共映射器映射(Func映射)
{
_dto=地图(实体);
归还这个;
}
公共映射器映射(操作映射)
其中TBaseDto:BaseDto
{
映射(实体,作为TBaseDto);
归还这个;
}
公共交通运输署
{
获取{return\u dto;}
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var studentEntity=new Entity(){FirstName=“John”,FamilyName=“Doe”,CourseId=1};
var studentDto=新映射器(studentEntity)
.Map(StudentDto.Map)
.Map(PersonDto.Map)
.结果;
}
}

我以前使用过Automapper,但我想知道“手动”方法会是什么样子,如果使用第三方库是不可能的呢?我认为OP不会希望在DTO之间创建映射,而是在实体和DTO之间创建映射。Automapper也可以用于此,但您的示例有误导性。@Andreas这是正确的,我应该在我的问题中更具体地说明实体到映射。是的,这更符合我的想法,为我提供了一个良好的起点。谢谢。
public class Entity
{
    public string FirstName { get; set; }
    public string FamilyName { get; set; }
    public int CourseId { get; set; }
    public int OccupationId { get; set; }
}

public class BaseDto
{

}

public class PersonDto : BaseDto
{
    public string FirstName { get; set; }
    public string FamilyName { get; set; }

    public static void Map(Entity entity, PersonDto personDto)
    {
        personDto.FirstName = entity.FirstName;
        personDto.FamilyName = entity.FamilyName;
    }

}

public class StudentDto : PersonDto
{
    public int CourseId { get; set; }

    public static StudentDto Map(Entity entity)
    {
        var studentDto = new StudentDto { CourseId = entity.CourseId };
        // ..can call map to PersonDto if you want
        return studentDto;
    }
}

public class EmployeeDto : PersonDto
{
    public int OccupationId { get; set; }

    public static EmployeeDto Map(Entity entity)
    {
        var employeeDto = new EmployeeDto() { OccupationId = entity.OccupationId };
        // ..can call map to PersonDto if you want
        return employeeDto;
    }
}


public class Mapper<TDto>
    where TDto : BaseDto
{
    private TDto _dto;
    private readonly Entity _entity;

    public Mapper(Entity entity)
    {
        _entity = entity;
    }

    public Mapper<TDto> Map(Func<Entity, TDto> map)
    {
        _dto = map(_entity);
        return this;
    }

    public Mapper<TDto> Map<TBaseDto>(Action<Entity, TBaseDto> map)
        where TBaseDto : BaseDto
    {
        map(_entity, _dto as TBaseDto);
        return this;
    }

    public TDto Result
    {
        get { return _dto; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        var studentEntity = new Entity() { FirstName = "John", FamilyName = "Doe", CourseId = 1 };

        var studentDto = new Mapper<StudentDto>(studentEntity)
            .Map(StudentDto.Map)
            .Map<PersonDto>(PersonDto.Map)
            .Result;
    }
}