AutoMapper don't work with entity EF Core

automapper c# entity-framework-core odata

Question

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

1
1
2/7/2018 11:35:36 AM

Accepted Answer

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
);
1
2/7/2018 12:48:38 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow