Исключение InvalidOperationException с $ top или $ skip в расширении OData

#entity-framework-core #odata #automapper

#entity-framework-core #odata #automapper

Вопрос:

Мы используем EF Core 3.1 с OData 7.5.1. Мы также используем DTO и Automapper 10.1.1 для сопоставления наших объектов с этими DTO.

Я пытаюсь развернуть только первые пару элементов во вложенной коллекции, используя следующий запрос:

https://localhost:44347/v1/odata/Subcategories ?$top=3$expand=Продукты ($top=2)

Если я выполняю этот запрос для объектов вместо DTO, все параметры запроса, добавленные в Expand, работают просто отлично.

Однако, если мы запустим это для DTO после ProjectTo, я получу следующее исключение:

[Сокращено для краткости]

 System.InvalidOperationException: Processing of the LINQ expression '(ProjectionBindingExpression: 0)' by 'RelationalProjectionBindingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
   at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
   at System.Linq.Expressions.ConditionalExpression.Accept(ExpressionVisitor visitor)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
   at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
  

Итак, это работает

         [AllowAnonymous, HttpGet]
        public async Task<IActionResult> Get(ODataQueryOptions<ProductSubcategoryDto> options)
        {
            IQueryable<ProductSubcategory> subs = DbContext.ProductSubcategories;
   
            IQueryable queryable = options.ApplyTo(subs); 
   
            return Ok(queryable);    
        }
  

но это выдает

         [AllowAnonymous, HttpGet]
        public async Task<IActionResult> Get(ODataQueryOptions<ProductSubcategoryDto> options)
        {   
            IQueryable<ProductSubcategoryDto> subsDto = DbContext.ProductSubcategories.ProjectTo<ProductSubcategoryDto>(Mapper.ConfigurationProvider);

            IQueryable queryable = options.ApplyTo(subsDto);    

            return Ok(queryable);
        }
  

И я также пробовал запрашиваемые расширения, и параметры запроса внутри расширения полностью игнорируются, кроме $select .

         [AllowAnonymous, HttpGet]
        public async Task<IActionResult> Get(ODataQueryOptions<ProductSubcategoryDto> options)
        {
             return Ok(await DbContext.ProductSubcategories.GetQueryAsync(Mapper, options));
        }
  

Все наши DTO и вызовы ProjectTo отлично работают вне этого контекста.

Я все делаю правильно? Это ошибка с EF Core или Automapper?

Комментарии:

1. github.com/AutoMapper/AutoMapper . Расширения. OData

2. Есть ли у вас средство отображения для продуктов, которые вы расширяете?

3. Спасибо @LucianBargaoanu. Я уже пробовал, и запрашиваемые расширения, похоже, также игнорируют $ skip и $ top в расширении. Я только что открыл проблему и там.

4. @Stutje да, я делаю. Сопоставление работает просто отлично везде. Это настолько просто, насколько это возможно для сопоставления с Product на ProductDto.

5. Я понял причину, по которой запрашиваемые расширения игнорируют эти запросы. Это потому, что мы вызываем EnableLowerCamelCase в EDM во время сборки, и имя элемента привязки сравнивается не с обновленными именами, а с исходным регистром Pascal для расширений. Подробности, изложенные в выпуске .