无法使用OData,EF Core和AutoMapper映射List <>导航属性

时间:2019-08-28 11:40:26

标签: c# asp.net-core entity-framework-core odata automapper

我目前正在编写一个使用OData进行查询的ASP.NET Core API,并使用Entity Framework与数据库进行通讯。

我想将域对象与发送给用户的DTO分开,因此也开始使用AutoMapper将实体框架查询结果转换为我创建的DTO。

在这一点上(我正在测试时),我的DTO和域对象是相同的-只是公共getter / setter属性。 DTO的示例如下:

    public class NoteDTO
    {
        public int Id { get; set; }
        public string Body { get; set; }
        public string Conclusion { get; set; }
        public string Title { get; set; }

        public ManagerDTO Manager { get; set; }
    }

    public class ManagerDTO
    {
        public int Id { get; set; }

        public virtual List<ProductDto> Products { get; set; }
    }

    public class ProductDto
    {
        public int Id { get; set; }
    }

我的NotesController中还有一个测试方法,用于获取笔记(再次使用OData),如下所示:

        [HttpGet]
        [EnableQuery]
        public IQueryable<NoteDTO> GetMeeting()
        {
            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<Note, NoteDTO>();
                cfg.CreateMap<Product, ProductDto>();
                cfg.CreateMap<Manager, ManagerDTO>()
                    .ForMember(md => md.Products, conf => conf.MapFrom(m => m.Products));
            });
            return _context.Notes.ProjectTo<NoteDTO>(config);
        }

然后我尝试使用以下查询命中我的API:

https://localhost:5001/api/Notes?$ select = Id,Body,Conclusion&$ top = 5&$ expand = Manager($ select = Id)

但是,这失败了,并且在堆栈跟踪中,给出了以下错误消息:

System.ArgumentException: Expression of type 'System.Collections.Generic.IEnumerable`1[System.Tuple`3[TestEntityFramework.DataObjects.ProductDto,Microsoft.EntityFrameworkCore.Query.Internal.MaterializedAnonymousObject,Microsoft.EntityFrameworkCore.Query.Internal.MaterializedAnonymousObject]]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable`1[TestEntityFramework.DataObjects.ProductDto]' of method 'System.Collections.Generic.IEnumerable`1[TestEntityFramework.DataObjects.ProductDto] _ToEnumerable[ProductDto](System.Collections.Generic.IEnumerable`1[TestEntityFramework.DataObjects.ProductDto])'

如果我从ManagerDTO对象和相关的产品映射配置中删除列表,则上面的查询将成功工作。

我在GitHub问题上看到了这个评论,听起来像是同样的问题,但是尝试实施该建议没有帮助(假设我已经正确理解了):https://github.com/AutoMapper/AutoMapper/issues/2853#issuecomment-482317381

还有其他人遇到这个问题吗?我仍然习惯于AutoMapper,因此可能错过了一些显而易见的事情,但是从四周搜索似乎是一个相当不常见的问题,因此很难获得关于这里发生的情况的指针。

对于将OData查询转换为实体框架然后再返回DTO的最佳方法,我也持开放态度,如果我在这里所做的不是最佳选择!

1 个答案:

答案 0 :(得分:0)

您是否正在使用Automapper集合扩展?如果没有,这应该可以解决您的问题:https://github.com/AutoMapper/AutoMapper.Collection