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

Improve Exception message: Cannot bind to constructor parameters #19383

Closed
Tracked by #240
Cooksauce opened this issue Dec 22, 2019 · 3 comments · Fixed by #26398
Closed
Tracked by #240

Improve Exception message: Cannot bind to constructor parameters #19383

Cooksauce opened this issue Dec 22, 2019 · 3 comments · Fixed by #26398
Labels
area-change-tracking area-docs area-o/c-mapping closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-enhancement
Milestone

Comments

@Cooksauce
Copy link

Error when running Add-Migration:
System.InvalidOperationException: No suitable constructor found for entity type 'ImmutableEntity'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'id', 'description' in 'ImmutableEntity(long id, string description)'.

Entity

public class ImmutableEntity
{
     public ImmutableEntity(long id, string description)
     {
          Id = id;
          Description = description ?? throw new ArgumentNullException(nameof(description));
     }

     public long Id { get; }
     public string Description { get; }
}

Reproduces with no other entities defined. Based on #10703, it seems like this should work. What are the requirements for EF to bind to the constructor params?

Further technical details

EF Core version: 3.1.0
Database provider: Npgsql
Target framework: .NET Core 3.0

@Cooksauce
Copy link
Author

Stacktrace:

System.InvalidOperationException: No suitable constructor found for entity type 'ImmutableEntity'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'id', 'description' in 'ImmutableEntity(long id, string description)'.
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.ConstructorBindingConvention.ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext`1 context)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IConventionModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IConventionModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel()
   at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel()
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
   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 Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

@Cooksauce
Copy link
Author

Whoops... didn't consider EF ignoring readonly properties by convention.

Fix: Call builder.Property(x => x.Id) and builder.Property(x => x.Description) so EF maps these properties. (and thus can bind them to the constructor params)

Suggestion

Add the following to the exception message:
EF may be ignoring readonly property(s) by convention. Consider calling 'Property(x => x.<YourProperty>)' to map a readonly property.

OR

Found readonly property(s) ['Id', 'Description'] which may be getting ignored by convention. Consider calling 'Property(x => x.<YourProperty>)' to map a readonly property.

@ajcvickers ajcvickers added this to the Backlog milestone Dec 26, 2019
@ajcvickers ajcvickers self-assigned this Dec 26, 2019
@SamVanheer
Copy link

It might be a good idea to also inform users if they're trying to bind a navigation property. I just tried to use it this way and it was not at all clear that this doesn't work.

@AndriySvyryd AndriySvyryd changed the title InvalidOperationException: Cannot bind to constructor parameters Improve Exception message: Cannot bind to constructor parameters Aug 13, 2020
@AndriySvyryd AndriySvyryd modified the milestones: Backlog, MQ Sep 2, 2020
ajcvickers added a commit that referenced this issue Oct 18, 2021
Fixes #19383
Fixes #17123

> No suitable constructor was found for entity type 'BlogNone'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'did' in 'BlogNone(string title, int did)'; cannot bind 'notTitle' in 'BlogNone(string notTitle, Guid? shadow, int id)'; cannot bind 'dummy' in 'BlogNone(string title, Guid? shadow, bool dummy, int id)'; cannot bind 'dummy', 'description' in 'BlogNone(string title, Guid? shadow, bool dummy, int id, string description)'. Note that only mapped properties can be bound to constructor parameters. Navigations to related entities, including references to owned types, cannot be bound.

Fixes #26341

> The 'DateOnly' property 'Blog.PostedOn' could not be mapped because the database provider does not support this type. Consider converting the property value to a type supported by the database using a value converter. See https://aka.ms/efcore-docs-value-converters for more information. Alternately, exclude the property from the model using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

Or if the store type is specified:

> The 'DateOnly' property 'Blog.PostedOn' could not be mapped to the database type 'datetime2' because the database provider does not support mapping 'DateOnly' properties to 'datetime2' columns. Consider mapping to a different database type or converting the property value to a type supported by the database using a value converter. See https://aka.ms/efcore-docs-value-converters for more information. Alternately, exclude the property from the model using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

Fixes #21954

> Cannot save instance of 'Skinner' because it is an owned entity without any reference to its owner. Owned entities can only be saved as part of an aggregate also including the owner entity.
@ajcvickers ajcvickers modified the milestones: MQ, 7.0.0 Oct 18, 2021
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Oct 18, 2021
ajcvickers added a commit that referenced this issue Oct 19, 2021
Fixes #19383
Fixes #17123

> No suitable constructor was found for entity type 'BlogNone'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'did' in 'BlogNone(string title, int did)'; cannot bind 'notTitle' in 'BlogNone(string notTitle, Guid? shadow, int id)'; cannot bind 'dummy' in 'BlogNone(string title, Guid? shadow, bool dummy, int id)'; cannot bind 'dummy', 'description' in 'BlogNone(string title, Guid? shadow, bool dummy, int id, string description)'. Note that only mapped properties can be bound to constructor parameters. Navigations to related entities, including references to owned types, cannot be bound.

Fixes #26341

> The 'DateOnly' property 'Blog.PostedOn' could not be mapped because the database provider does not support this type. Consider converting the property value to a type supported by the database using a value converter. See https://aka.ms/efcore-docs-value-converters for more information. Alternately, exclude the property from the model using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

Or if the store type is specified:

> The 'DateOnly' property 'Blog.PostedOn' could not be mapped to the database type 'datetime2' because the database provider does not support mapping 'DateOnly' properties to 'datetime2' columns. Consider mapping to a different database type or converting the property value to a type supported by the database using a value converter. See https://aka.ms/efcore-docs-value-converters for more information. Alternately, exclude the property from the model using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

Fixes #21954

> Cannot save instance of 'Skinner' because it is an owned entity without any reference to its owner. Owned entities can only be saved as part of an aggregate also including the owner entity.
@ajcvickers ajcvickers modified the milestones: 7.0.0, 7.0.0-preview1 Feb 14, 2022
@ajcvickers ajcvickers modified the milestones: 7.0.0-preview1, 7.0.0 Nov 5, 2022
@ajcvickers ajcvickers removed their assignment Sep 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-change-tracking area-docs area-o/c-mapping closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants