Проблема AutoMapper, отображающая сущность в словарь <Guid, строка> - PullRequest
2 голосов
/ 16 июля 2011

У меня возникла проблема с одной из моих конфигураций автоматического сопоставления, которую я не могу решить.

У меня есть объект типа contact, и я пытаюсь сопоставить их список столковый словарь.Однако отображение просто ничего не делает.Исходный словарь остается пустым.Кто-нибудь может предложить какие-либо предложения?

Ниже приведена упрощенная версия типа контакта

public class Contact
{
    public Guid Id { get; set ;}
    public string FullName { get; set; }
}

Моя конфигурация автоматического отображения выглядит следующим образом

Mapper.CreateMap<Contact, KeyValuePair<Guid, string>>()
    .ConstructUsing(x => new KeyValuePair<Guid, string>(x.Id, x.FullName));

И мой код вызова выглядитследующим образом

var contacts = ContactRepository.GetAll(); // Returns IList<Contact>
var options = new Dictionary<Guid, string>();
Mapper.Map(contacts, options);

Ответы [ 3 ]

10 голосов
/ 16 июля 2011

Это должно работать со следующим, Mapper не требуется ...

var dictionary = contacts.ToDictionary(k => k.Id, v => v.FullName);
5 голосов
/ 16 июля 2011

Документация очень краткая на веб-сайте AutoMapper. Из того, что я могу сказать, второй параметр в Mapper.Map используется только для определения типа возвращаемого значения и фактически не изменяется. Это связано с тем, что он позволяет выполнять динамическое сопоставление на основе существующего объекта, тип которого известен только во время выполнения, вместо жесткого кодирования типа в обобщениях.

Итак, проблема в вашем коде состоит в том, что вы не используете возвращаемое значение Mapper.Map, которое фактически содержит конечный преобразованный объект. Вот измененная версия вашего кода, которую я протестировал, и правильно возвращает преобразованные объекты, как вы ожидаете.

var contacts = ContactRepository.GetAll();
var options = Mapper.Map(contacts, new Dictionary<Guid, string>());
// options should now contain the mapped version of contacts

Хотя было бы эффективнее использовать универсальную версию вместо создания ненужного объекта, просто чтобы указать тип:

var options = Mapper.Map<List<Contact>, Dictionary<Guid, string>>(contacts);

Вот пример рабочего кода , который можно запустить в LinqPad (для запуска примера необходима ссылка на сборку AutoMapper.dll .)

Надеюсь, это поможет!

0 голосов
/ 14 февраля 2012

Другое решение в GitHub AutoMapper:

https://github.com/AutoMapper/AutoMapper/issues/51

oakinger [CodePlex] только что написал небольшой метод расширения, который решает это:

public static class IMappingExpressionExtensions 
{ 
public static IMappingExpression<IDictionary, TDestination> ConvertFromDictionary<TDestination>(this IMappingExpression<IDictionary, TDestination> exp, Func<string, string> propertyNameMapper) 
{ 
foreach (PropertyInfo pi in typeof(Invoice).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 
{ 
if (!pi.CanWrite || 
pi.GetCustomAttributes(typeof(PersistentAttribute), false).Length == 0) 
{ 
continue; 
} 

string propertyName = pi.Name; 
propertyName = propertyNameMapper(propertyName); 
exp.ForMember(propertyName, cfg => cfg.MapFrom(r => r[propertyName])); 
} 
return exp; 
} 
} 

Usage: 

Mapper.CreateMap<IDictionary, MyType>() 
.ConvertFromDictionary(propName => propName) // map property names to dictionary keys 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...