2012-04-02 10 views
5

Używam Automappera do pobrania dwóch obiektów tego samego typu i odwzorowania dowolnych nowych wartości, które uległy zmianie. Próbowałem użyć poniższego kodu, ale ciągle wyskakuje mi błąd i nie jestem nawet pewien, czy można to osiągnąć dzięki Automapperowi.AutoMapper - Mapa wykorzystująca te same typy obiektów źródłowych i docelowych

Na przykład:

 Mapper.CreateMap<UserDetails, UserDetails>(); 
     UserDetails userDetails = Mapper.Map<UserDetails, UserDetails>(userDetailsCurrent, userDetailsNew); 

Zasadniczo muszę skopiować całej żadnych nowych wartości, które pochodzą z nowego obiektu „userDetailsNew” do istniejącego obiektu „userDetailsCurrent” - mimo że są one tego samego typu . W ten sposób mogę "zaktualizować" istniejący obiekt o nowe wartości. Powodem, dla którego to robię, jest to, że nie jestem pewien, jakie dane użytkownika zostaną przekazane - muszę je zmapować, kiedy i kiedy się pojawią.

ja zwykle używany Automapper mapować różnych przedmiotów o podobnych właściwościach - ale myślałem, że mogę wykorzystać moc Automapper aby osiągnąć to samo w ten sposób. Może być nawet lepsze rozwiązanie - każda pomoc będzie doceniona!

+0

Czy 'Mapper.Map' powinien zwracać' UserDetails' lub 'UserSession'? –

+0

Powinien zwrócić UserDetails - Ive właśnie zaktualizował próbkę kodu. – Deano

+0

Jaki błąd jest zgłaszany? –

Odpowiedz

6

To wydaje się działać dla mnie. Mój typ niestandardowy:

class MyType 
{ 
    public int MyInt { get; set; } 
    public string MyString { get; set; } 
} 

mój kod mapowania:

Mapper.CreateMap<MyType, MyType>(); 
var source = new MyType() {MyInt = 1, MyString = "Hello world"}; 
var dest = Mapper.Map<MyType, MyType>(source); 

Co ciekawe o typu niestandardowego poza proste właściwości?

+0

To wygląda dobrze - nie jestem w pobliżu mojego komputera, więc sprawdzam to i wracam jak najszybciej! – Deano

+0

Czy istnieje sposób, że mogę to zrobić bez użycia ForMember()? Może to być czystsze, aby nie robić tego dla każdej właściwości obiektu. – Deano

+0

Tak, to nadal działa, jeśli nie robisz ForMember. Jestem przyzwyczajony do korzystania z tych, które początkowo zawierałem. –

4

Można to zrobić za pomocą krotek i tworząc niestandardowy konwerter pochodzący z klasy abstrakcyjnej TypeConverter Automappera.

Say miałeś źródłowy i docelowy klasę:

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public override string ToString() 
    { 
     return string.Format("Firstname: {0}, Lastname: {1}", FirstName, LastName); 
    } 
} 

Następnie można zbudować niestandardowy typ konwertera jako

public class CustomerPersonConverter : TypeConverter<Tuple<Person, Person>, Person> 
{ 
    protected override Person ConvertCore(Tuple<Person, Person> source) 
    { 
     var orginalValues = source.Item1; 
     var updatedValues = source.Item2; 

     var result = new Person 
      { 
       FirstName = string.IsNullOrEmpty(updatedValues.FirstName) ? orginalValues.FirstName : updatedValues.FirstName, 
       LastName = string.IsNullOrEmpty(updatedValues.LastName) ? orginalValues.LastName : updatedValues.LastName 
      }; 

     return result; 
    } 
} 

które mogłyby zostać wykorzystane jak

var orginal = new Person() {FirstName = "Clifford", LastName = "Mayson"}; 
     var updated = new Person() {FirstName = "Cliff"}; 

     Mapper.CreateMap<Tuple<Person, Person>, Person>().ConvertUsing<CustomerPersonConverter>(); 

     var result = Mapper.Map<Person>(new Tuple<Person, Person>(orginal, updated)); 

     Console.WriteLine(result); 

Która wygenerowałby wynik zachowania oryginalnej wartości nazwiska, której brakowało w aktualizacji, ale upda wartości imienia, np.

Firstname: Cliff, Lastname: Mayson 
+0

Dzięki za wyraźny przykład. – PratikSatikunvar

Powiązane problemy