dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.63k stars 3.15k forks source link

dbcontext scaffold introduces InvalidOperationException on Join Entity configuration for many-to-many relationships #29218

Closed jakebushlack closed 1 year ago

jakebushlack commented 1 year ago

Starting with an existing DB, I have scaffolded the tables into entities and a new ApplicationDbContext. When I configure the join entity in my ApplicationDbContext, I get an InvalidOperationException: Nullable object must have a value on one of two IndexerProperty. I am attempting to extend IdentityUser as AspNetUser and introduce ICollection navigation properties for foreign relationships. And when I say that I'm attempting this, I mean that I used the EF Core CLI to scaffold all new entities, but as soon as I target my ApplicationDbContext, I lose the ability to register new identities or log in as a known user each time failing on UsingEntity(String, Func<EntityTypeBuilder,ReferenceCollectionBuilder>, Func<EntityTypeBuilder,ReferenceCollectionBuilder>, Action)-system-func((microsoft-entityframeworkcore-metadata-builders-entitytypebuilder-microsoft-entityframeworkcore-metadata-builders-referencecollectionbuilder))-system-action((microsoft-entityframeworkcore-metadata-builders-entitytypebuilder)))) at IndexerProperty(String) For more context: StackOverflow: EF Core-generated Collection navigation property throws InvalidOperationException: Nullable object must return a value on ASP.NET Core login

I've checked for nullable columns and entity properties. I've made sure that all my data is sound. I'm not sure if this is more of an issue or a question, but I'm looking for some guidance what I may be doing wrong or need to change in my db context.

I've looked every day for a week on Stack Overflow, MS Docs, YouTube, etc to see if I'm missing anything from the db-first/reverse-engineering approach to EF Core. I haven't done anything more invasive than register my ApplicationDbContext and specify that SignInManager should use AspNetUser instead of IdentityUser

Stack trace:

InvalidOperationException: Nullable object must have a value.
Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.Property(Type propertyType, string propertyName, MemberInfo memberInfo, Nullable<ConfigurationSource> typeConfigurationSource, Nullable<ConfigurationSource> configurationSource)
Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.GetActualProperties(IReadOnlyList<Property> properties, Nullable<ConfigurationSource> configurationSource)
Microsoft.EntityFrameworkCore.Metadata.Internal.InternalIndexBuilder.Attach(InternalEntityTypeBuilder entityTypeBuilder)
Microsoft.EntityFrameworkCore.Metadata.Internal.PropertiesSnapshot.Attach(InternalEntityTypeBuilder entityTypeBuilder)
Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.Property(Type propertyType, string propertyName, MemberInfo memberInfo, Nullable<ConfigurationSource> typeConfigurationSource, Nullable<ConfigurationSource> configurationSource)
Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.IndexerProperty(Type propertyType, string propertyName, Nullable<ConfigurationSource> configurationSource)
Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder.IndexerProperty<TProperty>(string propertyName)
DataView.Data.ApplicationDbContext+<>c.<OnModelCreating>b__43_35(EntityTypeBuilder<Dictionary<string, object>> j) in ApplicationDbContext.cs
+
                            j.IndexerProperty<string>("DvSitegroup").HasMaxLength(50).IsUnicode(false).HasColumnName("DV_SITEGROUP").HasDefaultValueSql("('')");
Microsoft.EntityFrameworkCore.Metadata.Builders.CollectionCollectionBuilder<TLeftEntity, TRightEntity>.UsingEntity<TJoinEntity>(string joinEntityName, Func<EntityTypeBuilder<TJoinEntity>, ReferenceCollectionBuilder<TLeftEntity, TJoinEntity>> configureRight, Func<EntityTypeBuilder<TJoinEntity>, ReferenceCollectionBuilder<TRightEntity, TJoinEntity>> configureLeft, Action<EntityTypeBuilder<TJoinEntity>> configureJoinEntityType)
DataView.Data.ApplicationDbContext+<>c.<OnModelCreating>b__43_2(EntityTypeBuilder<AspNetUser> entity) in ApplicationDbContext.cs
+
                entity.HasMany(d => d.DvSitegroups)
Microsoft.EntityFrameworkCore.ModelBuilder.Entity<TEntity>(Action<EntityTypeBuilder<TEntity>> buildAction)
DataView.Data.ApplicationDbContext.OnModelCreating(ModelBuilder modelBuilder) in ApplicationDbContext.cs
+
            modelBuilder.Entity<AspNetUser>(entity =>
Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context)
Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, ModelDependencies modelDependencies)
Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, ModelCreationDependencies modelCreationDependencies, bool designTime)
Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel(bool designTime)
Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder+<>c.<TryAddCoreServices>b__8_4(IServiceProvider p)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine+<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService<T>(IServiceProvider provider)
Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
Microsoft.EntityFrameworkCore.DbContext.get_ContextServices()
Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
Microsoft.EntityFrameworkCore.DbContext.Set<TEntity>()
Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserOnlyStore<TUser, TContext, TKey, TUserClaim, TUserLogin, TUserToken>.get_UsersSet()
Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserOnlyStore<TUser, TContext, TKey, TUserClaim, TUserLogin, TUserToken>.get_Users()
Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserOnlyStore<TUser, TContext, TKey, TUserClaim, TUserLogin, TUserToken>.FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
Microsoft.AspNetCore.Identity.UserManager<TUser>.FindByNameAsync(string userName)
Microsoft.AspNetCore.Identity.SignInManager<TUser>.PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure)
DataView.Areas.Identity.Pages.Account.LoginModel.OnPostAsync(string returnUrl) in Login.cshtml.cs
+
                var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Convert<T>(object taskAsObject)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+GenericTaskHandlerMethod.Execute(object receiver, object[] arguments)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Product versions: EF Core version: 6 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 6 Operating system: Windows 10 IDE: Jetbrains Rider

ajcvickers commented 1 year ago

@jakebushlack Can you post the SQL schema that you are scaffolding the entity types and context from?

ajcvickers commented 1 year ago

EF Team Triage: Closing this issue as the requested additional details have not been provided and we have been unable to reproduce it.

BTW this is a canned response and may have info or details that do not directly apply to this particular issue. While we'd like to spend the time to uniquely address every incoming issue, we get a lot traffic on the EF projects and that is not practical. To ensure we maximize the time we have to work on fixing bugs, implementing new features, etc. we use canned responses for common triage decisions.