diff --git a/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs b/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs index 8dc5a0c526c..cd4f524c3c0 100644 --- a/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs +++ b/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs @@ -48,7 +48,8 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { - if (entityType.ClrType?.IsAbstract == false) + if (entityType.ClrType?.IsAbstract == false + && entityType.Builder.CanSetAnnotation(CoreAnnotationNames.ConstructorBinding, null)) { var maxServiceParams = 0; var minPropertyParams = int.MaxValue; diff --git a/test/EFCore.Tests/Metadata/Conventions/ConstructorBindingConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/ConstructorBindingConventionTest.cs index 2c8687c8fb7..dd44fb36c61 100644 --- a/test/EFCore.Tests/Metadata/Conventions/ConstructorBindingConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/ConstructorBindingConventionTest.cs @@ -383,6 +383,38 @@ public void Throws_if_two_constructors_with_same_number_of_parameters_could_be_u () => GetBinding()).Message); } + [ConditionalFact] + public void Does_not_throw_if_explicit_binding_has_been_set() + { + var constructorBinding = GetBinding( + e => e[CoreAnnotationNames.ConstructorBinding] = new ConstructorBinding( + typeof(BlogConflict).GetConstructor( + new[] + { + typeof(string), + typeof(int) + }), + new[] + { + new PropertyParameterBinding(e.FindProperty(nameof(Blog.Title))), + new PropertyParameterBinding(e.FindProperty(nameof(Blog.Id))) + })); + + Assert.NotNull(constructorBinding); + + var parameters = constructorBinding.Constructor.GetParameters(); + var bindings = constructorBinding.ParameterBindings; + + Assert.Equal(2, parameters.Length); + Assert.Equal(2, bindings.Count); + + Assert.Equal("title", parameters[0].Name); + Assert.Equal("id", parameters[1].Name); + + Assert.Equal("Title", bindings[0].ConsumedProperties.First().Name); + Assert.Equal("Id", bindings[1].ConsumedProperties.First().Name); + } + private class BlogConflict : Blog { public BlogConflict(string title, int id) @@ -747,7 +779,7 @@ private class NoFieldRelated public NoField NoField { get; set; } } - private ConstructorBinding GetBinding() + private ConstructorBinding GetBinding(Action setBinding = null) { var entityType = ((IMutableModel)new Model()).AddEntityType(typeof(TEntity)); entityType.AddProperty(nameof(Blog.Id), typeof(int)); @@ -762,6 +794,8 @@ private ConstructorBinding GetBinding() entityType.AddProperty("_FooBaar5", typeof(string)); entityType.AddProperty("m_FooBaar6", typeof(string)); + setBinding?.Invoke(entityType); + var model = (Model)entityType.Model; var context = new ConventionContext(model.ConventionDispatcher);