NP0007: A mapper reads lazy navigations of each element by naming convention
Default severity: Info (a suggestion in the IDE; not shown in command-line builds unless raised)
What it detects
An object mapper given EF entities (a whole result, or one element inside a loop) whose naming conventions read navigations the query did not include, while lazy loading is on:
var orders = await db.Orders.ToListAsync();
return orders.Adapt<List<OrderView>>(); // NP0007: OrderView.CustomerName flattens Customer.Name
return mapper.Map<List<LineView>>(lines); // NP0007 when no CreateMap<OrderLine, LineView> is visible
AutoMapper and Mapster both fill a destination member named like a navigation from it, and flatten names such as
CustomerName from Customer.Name. Each navigation read that way on each element is one more query.
Why it is a suggestion
The mapping configuration decides what is really read, and here it is not visible: the AutoMapper profile is in
another project, or there is none and the mapper relies on its conventions. When an AutoMapper
CreateMap<TSource, TDestination>() or a Mapster TypeAdapterConfig<TSource, TDestination>.NewConfig() (or
config.NewConfig<TSource, TDestination>(), ForType) is in the same project, its overrides (AutoMapper's
ForMember(..., o => o.MapFrom(...)) and Ignore(), Mapster's Map(d => d.X, s => ...) and Ignore(d => d.X)) are
applied and the reads are reported as NP0002, a warning.
How to fix it
Let the query build the destination, so it loads only what the view needs and nothing lazily:
var views = await db.Orders.ProjectTo<OrderView>(mapper.ConfigurationProvider).ToListAsync(); // AutoMapper
var views = await db.Orders.ProjectToType<OrderView>().ToListAsync(); // Mapster
or Include the navigations before mapping. Raise the rule to a warning once your mappings follow the
conventions: dotnet_diagnostic.NP0007.severity = warning.