Используйте Automapper для выравнивания подкласса собственности

Учитывая классы:

public class Person
{
    public string Name { get; set; }
}

public class Student : Person
{
    public int StudentId { get; set; }
}

public class Source
{
    public Person Person { get; set; }
}

public class Dest
{
    public string PersonName { get; set; }
    public int? PersonStudentId { get; set; }
}

Я хочу использовать Automapper для сопоставления Source -> Dest.

Этот тест явно не проходит:

Mapper.CreateMap<Source, Dest>();
var source = new Source() { Person = new Student(){ Name = "J", StudentId = 5 }};

var dest = Mapper.Map<Source, Dest>(source);
Assert.AreEqual(5, dest.PersonStudentId);

Каким будет лучший подход к отображению этого, учитывая, что «Person» на самом деле является широко используемым типом данных в нашей модели предметной области.

Изменить: цель состоит в том, чтобы сохранить объекты «Dest», поля которых будут определены для всех свойств подтипов «Person». Следовательно, мы могли бы иметь исходные объекты, подобные следующим, и предпочли бы не создавать объекты Dest для каждой возможной комбинации подклассов «Person»:

public class Source2
{
    public Person Value1 { get; set; }
    public Person Value2 { get; set; }
    public Person Value3 { get; set; }
    public Person Value4 { get; set; }
    public Person Value5 { get; set; }
}

person Neil    schedule 17.05.2010    source источник
comment
Просто любопытно, что произойдет, если Source.Person будет учителем с TeacherId вместо StudentId? Мы решаем эту проблему, создавая объект PersonDto вместе с типом StudentDto для обработки полиморфизма. В противном случае вы попадете в лисков нарушений.   -  person Jimmy Bogard    schedule 17.05.2010
comment
@Jimmy - отредактировал вопрос для дальнейшего уточнения. Person — это тип данных, который необходимо сопоставить с уровнем сохраняемости, который всегда имеет соответствующие поля, определенные для всех его возможных подтипов. В настоящее время мы решаем проблему подтипа в другом месте, просто надеясь, что есть более элегантное решение с помощью automapper.   -  person Neil    schedule 18.05.2010


Ответы (1)


Хорошо, используя предложение Джимми, я остановился на следующем решении:

public class Person
{
    public string Name { get; set; }
}

public class Student : Person
{
    public int StudentId { get; set; }
}
//all subtypes of person will map to this dto
public class PersonDto
{
    public string Name { get; set; }
    public int? StudentId { get; set; }
}

public class Source
{
    public Person Person { get; set; }
}

public class DestDto
{
    public PersonDto Person { get; set; }
}

public class Dest
{
    public string PersonName { get; set; }
    public int? PersonStudentId { get; set; }
}

[TestFixture]
public class RandomTests
{
    [Test]
    public void Test1()
    {
        Mapper.CreateMap<Person, PersonDto>();
        Mapper.CreateMap<Student, PersonDto>();

        Mapper.CreateMap<Source, DestDto>();
        Mapper.CreateMap<DestDto, Dest>();

        var source = new Source() { Person = new Student() { Name = "J", StudentId = 5 } };

        var destDto = Mapper.Map<Source, DestDto>(source);
        var destFinal = Mapper.Map<DestDto, Dest>(destDto);

        Assert.AreEqual(5, destFinal.PersonStudentId);
    }
}

Хотелось бы услышать предложения/улучшения.

person Neil    schedule 18.05.2010