Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Many-to-many includes no longer work on v4.0.0-beta1 #868

Closed
DumpsterDoofus opened this issue Oct 29, 2020 · 1 comment · Fixed by #869
Closed

Many-to-many includes no longer work on v4.0.0-beta1 #868

DumpsterDoofus opened this issue Oct 29, 2020 · 1 comment · Fixed by #869
Labels

Comments

@DumpsterDoofus
Copy link

DumpsterDoofus commented Oct 29, 2020

Description

Requesting related data of the form /resource1/{id}/resource2?include=resource1 worked in v4.0.0-alpha5, but seems to no longer work in v4.0.0-beta1.

Repro steps

To reproduce on v4.0.0-beta1:

  1. Pull Reproduce include bug DumpsterDoofus/JsonApiDotNetCore#1
  2. Run the src/Examples/IncludeBug project
  3. Make a request to GET /people/2/books?include=people
    • A 500 error is returned.

Stack trace:

fail: JsonApiDotNetCore.Middleware.ExceptionHandler[0]
      Property 'Int32 BookId' is not defined for type 'Test.Book' (Parameter 'property')
System.ArgumentException: Property 'Int32 BookId' is not defined for type 'Test.Book' (Parameter 'property')
   at MemberExpression System.Linq.Expressions.Expression.Property(Expression expression, PropertyInfo property)
   at MemberAssignment JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.CreatePropertyAssignment(PropertySelector selector, LambdaScope lambdaScope) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 131
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.CreateLambdaBodyInitializer(IDictionary<ResourceFieldAttribute, QueryLayer> selectors, ResourceContext resourceContext, LambdaScope lambdaScope, bool lambdaAccessorRequiresTestForNull)+(PropertySelector selector) => { } in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 64
   at bool System.Linq.Enumerable+SelectEnumerableIterator<TSource, TResult>.MoveNext()
   at void System.Collections.Generic.LargeArrayBuilder<T>.AddRange(IEnumerable<T> items)
   at T[] System.Collections.Generic.EnumerableHelpers.ToArray<T>(IEnumerable<T> source)
   at TSource[] System.Linq.Enumerable.ToArray<TSource>(IEnumerable<TSource> source)
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.CreateLambdaBodyInitializer(IDictionary<ResourceFieldAttribute, QueryLayer> selectors, ResourceContext resourceContext, LambdaScope lambdaScope, bool lambdaAccessorRequiresTestForNull) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 64
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.ApplySelect(IDictionary<ResourceFieldAttribute, QueryLayer> selectors, ResourceContext resourceContext) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 53
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.QueryableBuilder.ApplyProjection(Expression source, IDictionary<ResourceFieldAttribute, QueryLayer> projection, ResourceContext resourceContext) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs:line 112
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.QueryableBuilder.ApplyQuery(QueryLayer layer) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs:line 69
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.CreateCollectionInitializer(LambdaScope lambdaScope, PropertyInfo collectionProperty, Type elementType, QueryLayer layer, LambdaScopeFactory lambdaScopeFactory) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 174
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.CreateAssignmentRightHandSideForLayer(QueryLayer layer, LambdaScope outerLambdaScope, MemberExpression propertyAccess, PropertyInfo selectorPropertyInfo, LambdaScopeFactory lambdaScopeFactory) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 154
   at MemberAssignment JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.CreatePropertyAssignment(PropertySelector selector, LambdaScope lambdaScope) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 139
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.CreateLambdaBodyInitializer(IDictionary<ResourceFieldAttribute, QueryLayer> selectors, ResourceContext resourceContext, LambdaScope lambdaScope, bool lambdaAccessorRequiresTestForNull)+(PropertySelector selector) => { } in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 64
   at bool System.Linq.Enumerable+SelectEnumerableIterator<TSource, TResult>.MoveNext()
   at void System.Collections.Generic.LargeArrayBuilder<T>.AddRange(IEnumerable<T> items)
   at T[] System.Collections.Generic.EnumerableHelpers.ToArray<T>(IEnumerable<T> source)
   at TSource[] System.Linq.Enumerable.ToArray<TSource>(IEnumerable<TSource> source)
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.CreateLambdaBodyInitializer(IDictionary<ResourceFieldAttribute, QueryLayer> selectors, ResourceContext resourceContext, LambdaScope lambdaScope, bool lambdaAccessorRequiresTestForNull) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 64
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.SelectClauseBuilder.ApplySelect(IDictionary<ResourceFieldAttribute, QueryLayer> selectors, ResourceContext resourceContext) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SelectClauseBuilder.cs:line 53
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.QueryableBuilder.ApplyProjection(Expression source, IDictionary<ResourceFieldAttribute, QueryLayer> projection, ResourceContext resourceContext) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs:line 112
   at Expression JsonApiDotNetCore.Queries.Internal.QueryableBuilding.QueryableBuilder.ApplyQuery(QueryLayer layer) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs:line 69
   at IQueryable<TResource> JsonApiDotNetCore.Repositories.EntityFrameworkCoreRepository<TResource, TId>.ApplyQueryLayer(QueryLayer layer) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs:line 100
   at async Task<IReadOnlyCollection<TResource>> JsonApiDotNetCore.Repositories.EntityFrameworkCoreRepository<TResource, TId>.GetAsync(QueryLayer layer) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs:line 59
   at async Task<object> JsonApiDotNetCore.Services.JsonApiResourceService<TResource, TId>.GetSecondaryAsync(TId id, string relationshipName) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Services/JsonApiResourceService.cs:line 236
   at async Task<IActionResult> JsonApiDotNetCore.Controllers.BaseJsonApiController<TResource, TId>.GetSecondaryAsync(TId id, string relationshipName) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs:line 137
   at async Task<IActionResult> JsonApiDotNetCore.Controllers.JsonApiController<TResource, TId>.GetSecondaryAsync(TId id, string relationshipName) in C:/Users/e400092/source/repos/JsonApiDotNetCore/src/JsonApiDotNetCore/Controllers/JsonApiController.cs:line 59
   at async ValueTask<IActionResult> Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
   at TResult System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>.GetResult()
   at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()+Awaited(?)
   at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()+Awaited(?)
   at void Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
   at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
   at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextExceptionFilterAsync()+Awaited(?)

To confirm that the error does not occur on v4.0.0-alpha5:

  1. Pull Confirm that v4.0.0-alpha5 does not have the include bug DumpsterDoofus/JsonApiDotNetCore#2
  2. Run the src/Examples/IncludeBug project
  3. Make a request to GET /people/2/books?include=people
    • Succeeds, and returns person 2's books, and includes person 2.

Environment

  • JsonApiDotNetCore Version: v4.0.0-beta1
@bart-degreed
Copy link
Contributor

First of all, thanks for the excellent repro steps!

Despite that, it still took me several hours to investigate why this was going wrong. A big difference with alpha4 is that beta1 contains a complete redesign/rewrite for building expression trees.

Anyway, I have a fix available that I'm about to push shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

2 participants