Automapper Guid to string mapping与NullReferenceException失败,如果与Queryable Extensions一起使用的话

时间:2013-07-23 15:11:34

标签: automapper

我遇到了一个我似乎无法解决的映射问题。 这是模型:

public class Order
{
    public virtual Guid Id { get; set; }
    public virtual Client Client { get; set; }
}

public class Client
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Code { get; set; }
}

这是我要映射到的类:

public class OrderDto
{
    public string Id { get; set; }
    public string ClientCode { get; set; }
}

映射和测试:

public class AutomapperTest
{
    public AutomapperTest()
    {
        Mapper.Initialize(cfg => cfg.CreateMap<Order, OrderDto>()
            .ForMember(dto => dto.Id, conf => conf.MapFrom(p => p.Id))
            .ForMember(dto => dto.ClientCode, conf => conf.MapFrom(p => p.Client.Code)));
        Mapper.AssertConfigurationIsValid();
    }

    [Fact]
    public void MappingTest()
    {
        Client client = new Client { Id = Guid.NewGuid(), Code = "CTS" };
        Order order = new Order { Id = Guid.NewGuid(), Client = client };
        List<Order> orders = new List<Order> { order };

        List<OrderDto> list = orders.AsQueryable().Project().To<OrderDto>().ToList();
    }
}

尝试投影OrderDto对象列表时,测试失败并显示NullReferenceException。以下是来自Automapper的例外:

System.NullReferenceException
Object reference not set to an instance of an object.
   at AutoMapper.QueryableExtensions.Extensions.CreateMapExpression(IMappingEngine mappingEngine, Type typeIn, Type typeOut) in QueryableExtensions.cs: line 50
   at AutoMapper.QueryableExtensions.Extensions.CreateMapExpression(IMappingEngine mappingEngine, Type typeIn, Type typeOut) in QueryableExtensions.cs: line 136
   at AutoMapper.QueryableExtensions.Extensions.<>c__DisplayClass1`2.<CreateMapExpression>b__0(TypePair tp) in QueryableExtensions.cs: line 24
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at AutoMapper.Internal.DictionaryFactoryOverride.ConcurrentDictionaryImpl`2.GetOrAdd(TKey key, Func`2 valueFactory) in ConcurrentDictionaryFactory.cs: line 37
   at AutoMapper.QueryableExtensions.Extensions.CreateMapExpression(IMappingEngine mappingEngine) in QueryableExtensions.cs: line 21
   at AutoMapper.QueryableExtensions.ProjectionExpression`1.To() in QueryableExtensions.cs: line 251
   at AutoMapperIssue.AutomapperTest.MappingTest() in Class1.cs: line 47

如果未使用可查询扩展,则映射工作正常:

List<OrderDto> dtos = Mapper.Map<List<Order>, List<OrderDto>>(orders);

我错过了什么吗?

只是更新: 我正在NHibernate中使用它,得到完全相同的异常。

var fromDb = Session.Query<Order>().Project().To<OrderDto>().ToList();

似乎它在Guid上扼杀了字符串转换。如果我将Id字段注释掉,它对NHibernate和collection.AsQueryable()。

都适用
private static LambdaExpression CreateMapExpression(IMappingEngine mappingEngine, Type typeIn, Type typeOut)
{
    var typeMap = mappingEngine.ConfigurationProvider.FindTypeMapFor(typeIn, typeOut);
    ...
    foreach (var propertyMap in typeMap.GetPropertyMaps().Where(pm => pm.CanResolveValue()))
    {
    ...
    }
}

它在foreach上失败,因为typeMap为null。 typeIn = System.Guid typeOut = System.String

2 个答案:

答案 0 :(得分:0)

在3.1.1版本中需要引用两个dll:

AutoMapper和AitoMapper.Net4

在版本3.2.1中仍然存在问题

答案 1 :(得分:0)

这似乎是一个合法的限制。以下是作者explanation