DbContext model validation fails in LinqPad 6
LS,
I'm running into an issue querying my DbContext
in LinqPad 6. When querying any entity I get the following error:
Unable to determine the relationship represented by navigation 'Bid.PlacedByUser' of type 'User'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
It appears as if my IEntityTypeConfiguration
implementation is not being picked up by LinqPad. In Visual Studio the model validates and I am not getting this error and am able to perform operations on the DbContext
. The error message itself is clear, but in LinqPad it seems to be a false positive, as I'm quite confident the configuration itself is ok. See the relevant code below.
Any ideas how to solve this?
public class User { public ICollection<Bid> BidsPut { get; set; } public ICollection<Bid> BidsReceived { get; set; } } public class Bid { public int PlacedByUserId { get; set; } public User PlacedByUser { get; set; } public int ReceivedByUserId { get; set; } public User ReceivedByUser { get; set; } } public class BidConfiguration : IEntityTypeConfiguration<Bid> { public void Configure(EntityTypeBuilder<Bid> builder) { builder.HasOne(x => x.PlacedByUser) .WithMany(x => x.BidsReceived) .HasForeignKey(x => x.PlacedByUserId) .OnDelete(DeleteBehavior.Restrict); builder.HasOne(x => x.ReceivedByUser) .WithMany(x => x.BidsPut) .HasForeignKey(x => x.ReceivedByUserId) .OnDelete(DeleteBehavior.Restrict); } }
Here's the stack trace:
at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidatePropertyMapping(IModel model, IDiagnosticsLogger`1 logger) at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger) at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger) at Microsoft.EntityFrameworkCore.SqlServer.Internal.SqlServerModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger) at Microsoft.EntityFrameworkCore.Metadata.Conventions.ValidatingConvention.ProcessModelFinalized(IModel model) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IModel model) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IModel model) at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel() at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel() at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, ModelDependencies modelDependencies) at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, ModelDependencies modelDependencies) at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel() at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_3(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider() at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance() at Microsoft.EntityFrameworkCore.Infrastructure.Internal.InfrastructureExtensions.GetService[TService](IInfrastructure`1 accessor) at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor) at LINQPad.Drivers.EFCore.EFHelper.InitializeContext(IConnectionInfo cxInfo, Object context, QueryExecutionManager executionManager, Version efVersion) at LINQPad.Drivers.EFCore.StaticDriver.InitializeContext(IConnectionInfo cxInfo, Object context, QueryExecutionManager executionManager) at LINQPad.ExecutionModel.ClrQueryRunner.Run() at LINQPad.ExecutionModel.Server.RunQuery(QueryRunner runner)
Comments
Adding
InverseProperty
attributes to the navigation properties seems to resolve the issue. Could it be that LinqPad is only compatible with EF Core property attributes?Also, another issue that leads me to suspect that
IEntityTypeConfiguration
is not picked up by LinqPad is the fact that my custom schema names are not taken into account, which leads toInvalid object name
exceptions when executing queries.Can you post your DbContext class?
I think I've pinpointed the issue. I'm using the following for applying all entity type configurations:
modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly);
When explicitly registering an entity type configuration, it does seem to work. E.g.:
modelBuilder.ApplyConfiguration(new BidConfiguration());
Yes, that will be your problem. LINQPad subclasses your DbContext, so GetType().Assembly will return a different assembly, i.e., the assembly of your query.
You can fix this by being explicit about the type:
modelBuilder.ApplyConfigurationsFromAssembly(typeof (MyDbContextType).Assembly);