2010-05-17 82 views
1

子類的給定類:使用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映射源 - >目的地。

這個測試顯然會失敗:

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); 

什麼將映射最好的辦法這因爲「人」實際上是一個頻繁使用的數據類型在我們的域模型。

編輯:意圖是堅持「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; } 
} 
+0

只是好奇,如果Source.Person是一名教師,而TeacherId而不是StudentId會發生什麼? 我們通過創建一個PersonDto對象和一個處理多態性的StudentDto類型來解決這個問題。否則,你會陷入Liskov違規行爲。 – 2010-05-17 12:56:46

+0

@Jimmy - 編輯該問題以進一步澄清。 「Person」是一種數據類型,它需要映射到一個持久層,*永遠*具有爲其所有可能的子類型定義的適當字段。我們目前正在處理其他地方的子類型問題,只是希望通過automapper提供更優雅的解決方案。 – Neil 2010-05-18 01:28:01

回答

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); 
    } 
} 

很想聽到建議/改進。