I'm trying to get view from entity with fields that I specify at expandProperties with .ProjectTo(). Using .Net Core 2 + Ef Core + AutoMapper
There is entities:
public class LessonCatalog {
public string Name { get; set; }
public int? ImageId { get; set; }
public virtual Image Image { get; set; }
public virtual ICollection<Lesson> Lessons { get; set; }
}
public class Lesson {
public string Name { get; set; }
public string Description { get; set; }
public int? ImageId { get; set; }
public virtual Image Image { get; set; }
public int LessonCatalogId { get; set; }
public virtual LessonCatalog LessonCatalog { get; set; }
}
Views:
public class LessonView {
public string Name { get; set; }
public string Description { get; set; }
public int? ImageId { get; set; }
public ImageView Image { get; set; }
public int LessonCatalogId { get; set; }
public LessonCatalogView LessonCatalog { get; set; }
}
public class LessonCatalogView {
public string Name { get; set; }
public int? ImageId { get; set; }
public ImageView Image { get; set; }
public IEnumerable<LessonView> Lessons { get; set; }
}
My maps:
CreateMap<LessonCatalog, LessonCatalogView>()
.ForMember(dest => dest.Image, map => map.ExplicitExpansion())
.ForMember(dest => dest.Lessons, map => map.ExplicitExpansion());
CreateMap<Lesson, LessonView>()
.ForMember(dest => dest.LessonCatalog, map => map.ExplicitExpansion());
In my repository:
protected readonly DbContext _context;
protected readonly DbSet<TEntity> _entities;
public Repository(DbContext context) {
_context = context;
_entities = context.Set<TEntity>();
}
public IEnumerable<TView> GetOData<TView>(ODataQueryOptions<TView> query,
Expression<Func<TEntity, bool>> predicate = null) {
IQueryable<TEntity> repQuery = _entities.AsQueryable();
IQueryable res;
if (predicate != null) repQuery = _entities.Where(predicate);
if (query != null) {
string[] expandProperties = GetExpands(query);
//!!!
res = repQuery.ProjectTo<TView>(Mapper.Configuration, expandProperties);
//!!!
var settings = new ODataQuerySettings();
var ofilter = query.Filter;
var orderBy = query.OrderBy;
var skip = query.Skip;
var top = query.Top;
if (ofilter != null) res = ofilter.ApplyTo(res, settings);
if (orderBy != null) res = orderBy.ApplyTo(res, settings);
if (skip != null) res = skip.ApplyTo(res, settings);
if (top != null) res = top.ApplyTo(res, settings);
} else {
res = repQuery.ProjectTo<TView>(Mapper.Configuration);
}
return (res as IQueryable<TView>).AsEnumerable();
}
expandProperties
consist "Lessons" string, but after .ProjectTo()
I have null at Lessons field, and it's the same for all other entities at my project.
In the same ASP .Net 4.5 project with Entity FrameWork it's works fine. I feel I missing something important, at this case. There is may be a better way to get View with properties that I specify at odata expand query.
My packages: AutoMapper 6.2.2, Microsoft.EntityFrameworkCore 2.0, Microsoft.AspNetCore.OData 7.0.0-beta 1
You are hitting the wrong ProjectTo
overload.
repQuery.ProjectTo<TView>(Mapper.Configuration, expandProperties);
is calling
public static IQueryable<TDestination> ProjectTo<TDestination>(
this IQueryable source,
IConfigurationProvider configuration,
object parameters,
params Expression<Func<TDestination, object>>[] membersToExpand
);
i.e. the expandProperties
maps to object parameters
argument and have no effect.
Make sure you call ProjectTo
overload having params string[] membersToExpand
argument, for instance
repQuery.ProjectTo<TView>(Mapper.Configuration, null, expandProperties);
which matches
public static IQueryable<TDestination> ProjectTo<TDestination>(
this IQueryable source,
IConfigurationProvider configuration,
IDictionary<string, object> parameters,
params string[] membersToExpand
);