Ich habe eine ASP.NET 5 (läuft auf 4.6.2, nicht Core) -Anwendung. Ich wollte die ProjectTo <>() -Methode von AutoMapper verwenden, um die Ergebnisse von der Datenbank zu meinen Viewmodels zu projizieren.AutoMapper ProjectTo <>() finde keine Karte
Ich habe viele Tests ausprobiert, aber es scheint, dass die Karte bei der Verwendung von ProjectTo <>() nicht gefunden werden kann. Die Verwendung von mapper.Map <>() an verschiedenen Orten mit dem gleichen Modell und Viewmodel funktioniert perfekt.
Ich denke, es ist etwas falsch mit AutoMapper funktioniert mit meinem DI (Autofac), aber ich kann nicht herausfinden, was.
Wie auch immer, der Code:
Startup.Cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
(...)
// Autofac DI
AutofacContainer = AutofacLoader.Configure(services).Build();
return AutofacContainer.Resolve<IServiceProvider>();
}
AutofacLoader.cs
public static ContainerBuilder Configure(IServiceCollection services)
{
var builder = new ContainerBuilder();
(...)
// AutoMapper
builder.RegisterModule<AutoMapperModule>();
if (services != null)
{
builder.Populate(services);
}
return builder;
}
AutoMapperModule.cs
public class AutoMapperModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var mapping = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new Core.Mappings.AutoMapperProfileConfiguration());
cfg.AddProfile(new Dieet.Core.Mappings.AutoMapperProfileConfiguration());
});
builder.RegisterInstance(mapping.CreateMapper()).As<IMapper>().AutoActivate();
}
}
Der Test, der mit nicht ‚vermisste Karte von Patient zu PatientViewModel. Erstellen Sie mit Mapper.CreateMap '.
[Fact]
public async void InfohosServiceReturnsPatientViewModels()
{
var db = _container.Resolve<IInfohosDb>();
var search = new PaginatedSearchBase();
search.OrderBy = "Naam";
var mapper = _container.Resolve<IMapper>();
var result = await search.PagedResultAsAsync<Patient,PatientViewModel >(null,db.Patienten,mapper);
}
PaginatedSearchBase
public class PaginatedSearchBase
{
public string OrderBy { get; set; }
public bool OrderDescending { get; set; }
public int Page { get; set; } = 1;
public int PageSize { get; set; } = 10;
}
und schließlich die Erweiterung, die die ProjectTo
public static class PagedResultExtensions
{
public static async Task<PagedResult<T>> PagedResultAsync<T>(this PaginatedSearchBase vm, ICollection<Expression<Func<T, bool>>> whereCollection, IEnumerable<T> context) where T : class
{
int totalCount;
var query = PrepareQuery(vm, whereCollection, context, out totalCount);
return new PagedResult<T>
{
Results = await query.ToListAsync(),
Page = vm.Page,
PageSize = vm.PageSize,
Total = totalCount
};
}
public static async Task<PagedResult<TAs>> PagedResultAsAsync<T, TAs>(this PaginatedSearchBase vm, ICollection<Expression<Func<T, bool>>> whereCollection, IEnumerable<T> context, IMapper mapper) where T : class
{
int totalCount;
var query = PrepareQuery(vm, whereCollection, context, out totalCount);
return new PagedResult<TAs>
{
----------> Results = await query.ProjectTo<TAs>(mapper).ToListAsync(),
Page = vm.Page,
PageSize = vm.PageSize,
Total = totalCount
};
}
private static IQueryable<T> PrepareQuery<T>(PaginatedSearchBase vm, ICollection<Expression<Func<T, bool>>> whereCollection, IEnumerable<T> context,
out int totalCount) where T : class
{
var query = context.AsQueryable();
if (whereCollection != null)
{
foreach (var w in whereCollection)
{
if (w != null)
{
query = query.Where(w);
}
}
}
// Order by
query = query.OrderBy($"{vm.OrderBy} {(vm.OrderDescending ? "DESC" : "ASC")}");
// Total rows
totalCount = query.Count();
// Paging
query = query.Skip((vm.Page - 1)*vm.PageSize).Take(vm.PageSize);
return query;
}
}
Informationen nennt, ich bin mit Versionen:
- "Autofac": " 4.0.0-rc1-177 "
- "Autofac.Extensions.DependencyInjection": "4.0.0-rc1-177"
- "AutoMapper": "4.2.1"
Edit:
Ein neuer Test, dass ich hat zu überprüfen, ob die Zuordnungen wirklich funktionieren:
var mapper = _container.Resolve<IMapper>();
var p = new Patient();
p.Naam = "Test";
var vm = mapper.Map<PatientViewModel>(p);
vm.Naam.ShouldBeEquivalentTo("Test");
Dieser Test
gehtEdit 2:
Wenn ich die Karte <> in einer Select() statt, es funktioniert auch, es ist also wirklich die ProjectTo <>(), die fehlschlägt:
var results = await query.ToListAsync();
return new PagedResult<TAs>
{
Results = results.Select(mapper.Map<TAs>).ToList(),
Page = vm.Page,
PageSize = vm.PageSize,
Total = totalCount
};
Dies funktioniert, aber es erfordert, dass der Mapper einbezogen wird und nicht injiziert wird, und er verwendet nicht den ProjectTo, den Automapper für den Datenbankzugriff hat ...
Sie können versuchen, "mit AutoMapper.QueryableExtensions;" –
Ich verwende Visual Studio zum code, der Compiler gibt einen Fehler, wenn es nicht in den 'usings' ist. Die Methode wird aufgerufen, sie kann jedoch nicht die Instanz von IMapper oder etwas erhalten. Sie findet die Map nicht. – AppSum