我的一个映射有问题,我似乎无法解决。这是模型:
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
如果不使用 Queryable Extension,映射就可以正常工作:
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()))
{
...
}
}
由于 typeMap 为空,它在 foreach 上失败。typeIn = System.Guid typeOut = System.String