2012-04-02 4 views
5

Я использую Automapper для того, чтобы взять два объекта одного типа и отобразить все новые значения, которые были изменены. Я попытался использовать код ниже, но он продолжает бросать ошибку, и я даже не уверен, что это может быть достигнуто с помощью Automapper.AutoMapper - карта, использующая те же типы объектов источника и назначения

Например:

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

В принципе, мне нужно скопировать через любые новые значения, которые пришли из нового объекта «userDetailsNew» к существующему объекту «userDetailsCurrent» - несмотря на то, что они того же типа , Таким образом, я могу «обновить» существующий объект новыми значениями. Причина, по которой я делаю это, - это то, что я не уверен, какие данные пользователя будут переданы. Мне нужно сопоставить их по мере их поступления.

Я обычно использовал Automapper для сопоставления различных объектов со схожими свойствами - но я думал, что могу использовать силу Automapper для достижения такой же цели таким образом. Там может быть даже лучшее решение - любая помощь будет оценена!

+0

Должен ли 'Mapper.Map' возвращать' UserDetails' или 'UserSession'? –

+0

Он должен возвращать UserDetails - Ive просто обновил образец кода. – Deano

+0

Какая ошибка возникает? –

ответ

6

Это, похоже, работает на меня. Мой пользовательский тип:

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

Мой картирование код:

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

Что интересно пользовательского типа за пределами простых свойств?

+0

Это выглядит хорошо - я не рядом с моим ПК, поэтому я проверю это и вернусь как можно скорее! – Deano

+0

Есть ли способ, которым я могу это сделать, не используя ForMember()? Возможно, было бы более чистым не делать этого для каждого свойства объекта. – Deano

+0

Да, это все еще работает, если вы не делаете ForMember. Я просто привык к тому, чтобы использовать те, которые я включил в него. –

4

Это можно сделать с помощью кортежей и путем создания преобразователя пользовательского типа, полученного из класса абстрактного TypeConverter от Automapper.

Допустим, у вас есть класс источника и назначения:

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

Тогда вы могли бы построить пользовательский тип конвертера как

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

который может быть использован как

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

Какие приведет к результату сохранения исходного значения имени, отсутствующего в обновлении, но upda ting значение первого имени, например.

Firstname: Cliff, Lastname: Mayson 
+0

Спасибо за очевидный пример. – PratikSatikunvar

Смежные вопросы