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

Cannot use same property for multiple relations. #23179

Closed
atrauzzi opened this issue Nov 3, 2020 · 1 comment
Closed

Cannot use same property for multiple relations. #23179

atrauzzi opened this issue Nov 3, 2020 · 1 comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@atrauzzi
Copy link

atrauzzi commented Nov 3, 2020

Until polymorphic relations can be supported, I am trying to take an existing schema and create some useful navigation properties out of it. Unfortunately, I've been thwarted on a number of fronts, although it feels like the closest I've been able to get is via something along these lines:

    public class Entitlement
    {
        public Guid Id { get; set; }
        public Guid EntitleableId { get; set; }
    }

    public class Tenant
    {
        public Guid Id { get; set; }

        public ICollection<Entitlement> AssignedEntitlements { get; set; }
    }

    // note: Consider User and Firm the same as tenant in this example.
            // ...

            modelBuilder
                .Entity<Tenant>()
                .HasMany((tenant) => tenant.AssignedEntitlements)
                .WithOne()
                .IsRequired(true)
                .HasForeignKey((entitlement) => entitlement.EntitleableId)
                .HasPrincipalKey((tenant) => tenant.Id);

            modelBuilder
                .Entity<Firm>()
                .HasMany((firm) => firm.AssignedEntitlements)
                .WithOne()
                .IsRequired(true)
                .HasForeignKey((entitlement) => entitlement.EntitleableId)
                .HasPrincipalKey((firm) => firm.Id);

            modelBuilder
                .Entity<User>()
                .HasMany((user) => user.AssignedEntitlements)
                .WithOne()
                .IsRequired(true)
                .HasForeignKey((entitlement) => entitlement.EntitleableId)
                .HasPrincipalKey((user) => user.Id);

            // ...

I can't seem to retrieve anything when using something like:

dbContext.Tenants.Include((t) => t.AssignedEntitlements);

Entity framework generates a valid query (.ToQueryString()):

SELECT t.id, t.created_at, t."default", t.deleted_at, t.label, t.name, t.updated_at, e.id, e.created_at, e.entitleable_id, e.entitleable_type, e.feature, e.source_id, e.source_type, e.updated_at
FROM tenants AS t
         LEFT JOIN entitlements AS e ON t.id = e.entitleable_id
ORDER BY t.id, e.id

Running the generated SQL returns the correct data, but any attempt to run .First() on the query object seems to cause issues:

System.InvalidOperationException: Sequence contains no matching element
   at System.Linq.ThrowHelper.ThrowNoMatchException()
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
   at MyProject.Conventions.Feature..ctor(String name)
   at lambda_method374(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator )
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<PopulateIncludeCollection>g__ProcessCurrentElementRow|60_0[TIncludingEntity,TIncludedEntity](<>c__DisplayClass60_0`2& )
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.PopulateIncludeCollection[TIncludingEntity,TIncludedEntity](Int32 collectionId, QueryContext queryContext, DbDataReader dbDataReader, SingleQueryResultCoordinator resultCoordinator, Func`3 parentIdentifier, Func`3 outerIdentifier, Func`3 selfIdentifier, IReadOnlyList`1 parentIdentifierValueComparers, IReadOnlyList`1 outerIdentifierValueComparers, IReadOnlyList`1 selfIdentifierValueComparers, Func`5 innerShaper, INavigationBase inverseNavigation, Action`2 fixup, Boolean trackingQuery)
   at lambda_method376(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator )
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at lambda_method377(Closure , QueryContext )
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
   at MyProject.Global.Api.Controller.TestController.Test(MyProjectGlobalContext context) in /home/me/Development/MyProject/global/MyProject.Global.Api/src/Controller/TestController.cs:line 19
   at lambda_method289(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

@atrauzzi
Copy link
Author

atrauzzi commented Nov 3, 2020

I'm quite blocked by this at the moment, so I've mirrored this issue to Stack Overflow.

Ahh, PEBKAC! I totally forgot about configuring my own dang value type. All fixed now.

@atrauzzi atrauzzi closed this as completed Nov 3, 2020
@AndriySvyryd AndriySvyryd added the closed-no-further-action The issue is closed and no further action is planned. label Nov 4, 2020
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

3 participants