#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 для расширений. Подробности, изложенные в выпуске .