AutoMapper问题将实体映射到Dictionary <guid,string =“”> </guid,>

时间:2011-07-15 21:20:10

标签: c# asp.net-mvc automapper

我遇到了一个我似乎无法解决的自动配置问题。

我有一个类型联系的实体,我正在尝试将这些列表映射到字典。但是,映射只是没有做任何事情。源字典保持为空。任何人都可以提出任何建议吗?

以下是联系人类型

的简化版本
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 个答案:

答案 0 :(得分:10)

这应该适用于以下内容,不需要Mapper ......

var dictionary = contacts.ToDictionary(k => k.Id, v => v.FullName);

答案 1 :(得分:5)

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中运行的working code sample(运行示例需要AutoMapper.dll的程序集引用。)

希望这有帮助!

答案 2 :(得分:0)

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