Why is Automapper.ProjectTo() throwing a null reference exception?

流过昼夜 提交于 2020-08-10 04:02:21

问题


I have a mapping:

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.
});

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());

When I query the entities directly:

var id = "123";
var bar = this.mockContext.Object.Foo.Where(p => p.id == id);

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);

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?


回答1:


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() });

allows the ProjectTo method to complete, albeit with null values.



来源:https://stackoverflow.com/questions/43240089/why-is-automapper-projectto-throwing-a-null-reference-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!