为什么Automapper.ProjectTo()抛出空引用异常? [英] Why is Automapper.ProjectTo() throwing a null reference exception?
问题描述
我有一个映射:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Foo, FooDto>()
.ForMember(dest => dest.Id,
opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.Name,
opt => opt.MapFrom(src => src.Name))
.ForMember(dest => dest.PhoneNumber,
opt => opt.MapFrom(src => src.PhoneNumbers.Number)) //etc.
});
并且我正试图在单元测试中使用它来调用一些模拟的EF对象:
and I'm trying to use it in a unit test calling into some mocked up EF objects:
var ids = new List<string>()
{
"123";
"456";
"789";
};
var data = new List<Foo>();
foreach(var id in ids)
{
data.Add(new Foo() { Id = id });
}
this.mockContext = new Mock<entities>();
this.mockSet = new Mock<DbSet<Foo>>();
this.mockSet.As<IQueryable<Foo>>().Setup(p => p.Provider).Returns(data.Provider);
this.mockSet.As<IQueryable<Foo>>().Setup(p => p.Expression).Returns(data.Expression);
this.mockSet.As<IQueryable<Foo>>().Setup(p => p.ElementType).Returns(data.ElementType);
this.mockSet.As<IQueryable<Foo>>().Setup(p => p.GetEnumerator()).Returns(data.GetEnumerator());
当我直接查询实体时:
var id = "123";
var bar = this.mockContext.Object.Foo.Where(p => p.id == id);
我按预期返回了一个结果为IQueryable()的结果.但是,当我尝试将对象投影到DTO中时:
I get back an IQueryable() with a single result, as expected. But when I try to project my object into a DTO:
var id = "123";
var buzz = this.mockContext.Object.Foo.Where(p => p.id == id).ProjectTo<FooDto>(this.config);
如果我尝试以任何方式访问结果,我返回的IQueryable都会引发Null引用异常.例如:
The IQueryable I get back throws a Null Reference Exception if I try to access the results in any way. So for example:
buzz.ToList();
buzz.SingleOrDefault(); // This mirrors the actual call in my code since this is a GetById query.
都失败了.我在这里想念什么?
both fail. What am I missing here?
推荐答案
问题在于,Foo
使用EF导航属性引用其他对象.在这种情况下,特别是PhoneNumber
.由于创建的测试数据没有链接的PhoneNumber
对象,因此它会破坏ProjectTo
方法的内部.当直接获取顶级Queryable时,这不是问题,但是Automapper需要对象存在(即使它们为空)才能完成映射.将该行更改为:
The problem lies is that Foo
uses EF navigation properties to refer to other objects. Specifically a PhoneNumber
in this instance. Since the test data is created without the linked PhoneNumber
object, it breaks inside of the ProjectTo
method. This isn't a problem when grabbing the top level Queryable directly, but Automapper needs the objects to exist (even if they're empty) in order to complete the mapping. Changing that line to:
data.Add(new Foo() { Id = id, PhoneNumber = new PhoneNumber() });
允许ProjectTo
方法完成,尽管其值为空.
allows the ProjectTo
method to complete, albeit with null values.
这篇关于为什么Automapper.ProjectTo()抛出空引用异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!