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

Different value generation strategies on Owned Entity Types #20740

Closed
jochenjonc opened this issue Apr 24, 2020 · 4 comments
Closed

Different value generation strategies on Owned Entity Types #20740

jochenjonc opened this issue Apr 24, 2020 · 4 comments
Labels
area-model-building closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported punted-for-5.0 type-bug
Milestone

Comments

@jochenjonc
Copy link

When trying Preview 3 of EF Core 5, to see if issue #18299 that has been solved, also solves my issue #19907, I got stuck on the following error.

'Contact.Id' and 'Contact.Location#Location.Address#Address.LocationContactId' are both mapped to column 'Id' in 'Contact' but are configured with different value generation strategies.

I didn't have this error on Preview 2 and on EF Core 2.2.

Steps to reproduce

I have the following entities and owned types:

public class Contact : Entity
{
	protected Contact()
	{
		Location = new Location();
	}

	public string Name { get; set; }
	public Location Location { get; protected set; }
}

public class Location
{
	private Address _address = new Address();

	public Address Address
	{
		get => _address;
		set => _address = value ?? throw new ArgumentNullException(nameof(Address));
	}

	public Point Coordinates { get; set; }
}

public class Address
{
	public string Street { get; set; }
	public string Number { get; set; }
	public string ZipCode { get; set; }
	public string City { get; set; }
	public string Country { get; set; }
}

The EntityTypeConfiguration is as follows:

public class ContactEntityTypeConfiguration : IEntityTypeConfiguration<Contact>
{
	public void Configure(EntityTypeBuilder<Contact> builder)
	{
		builder.Property(c => c.Id)
			.UseHiLo("ContactHiLoSequence");

		builder.Property(c => c.Name)
			.IsUnicode()
			.HasMaxLength(150);

		builder.OwnsOne(c => c.Location,  l =>
		{
			l.OwnsOne(la => la.Address, la =>
			{
				la.Property(a => a.Street).HasColumnName("Street");
				la.Property(a => a.Number).HasColumnName("Number");
				la.Property(a => a.ZipCode).HasColumnName("ZipCode");
				la.Property(a => a.City).HasColumnName("City");
				la.Property(a => a.Country).HasColumnName("Country");
			}).WithOwner();

			l.Property(lc => lc.Coordinates).HasColumnName("Coordinates");
		});
	}
}

When fetching the Contact entity in EF Core 5 Preview 3 I get the error mentioned above.

Here is the full stacktrace:

[09:20:25 ERR] HTTP GET /api/contacts responded 500 in 3864.6813 ms
System.InvalidOperationException: 'Contact.Id' and 'Contact.Location#Location.Address#Address.LocationContactId' are both mapped to column 'Id' in 'Contact' but are configured with different value generation strategies.
   at Microsoft.EntityFrameworkCore.SqlServer.Internal.SqlServerModelValidator.ValidateCompatible(IProperty property, IProperty duplicateProperty, String columnName, String tableName)
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.ValidateSharedColumnsCompatibility(IReadOnlyList`1 mappedTypes, String tableName, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.SqlServer.Internal.SqlServerModelValidator.ValidateSharedColumnsCompatibility(IReadOnlyList`1 mappedTypes, String tableName, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.ValidateSharedTableCompatibility(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)
   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.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.Set[TEntity]()
   ...
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   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.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
   at lambda_method(Closure , IServiceProvider , Object[] )
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.<CreateActivator>b__0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
   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 where exception was thrown ---
   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.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)

Further technical details

EF Core version: 5 Preview 3
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: NET Core 3.1.1
Operating system: Windows 10
IDE: Visual Studio 2019 16.5.4

@ajcvickers
Copy link
Member

@jochenjonc Thanks for reporting this. As a workaround you can explicitly configure the shadow key property in the owned types:

builder.OwnsOne(c => c.Location,  l =>
{
    l.Property<int>("ContactId").UseHiLo("ContactHiLoSequence");
    l.OwnsOne(la => la.Address, la =>
    {
        la.Property<int>("LocationContactId").UseHiLo("ContactHiLoSequence");
        ...
    }).WithOwner();
    ...
});

@jochenjonc
Copy link
Author

@ajcvickers with the workaround, the query that is no being produced by EF for issue #19907 is a lot better now. Thx.

@AndriySvyryd AndriySvyryd added the verify-fixed This issue is likely fixed in new query pipeline. label Jun 10, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0, Backlog Jul 20, 2020
@bricelam bricelam modified the milestones: Backlog, MQ Sep 11, 2020
@AndriySvyryd AndriySvyryd modified the milestones: MQ, 6.0.0 Nov 5, 2020
@AndriySvyryd AndriySvyryd removed the verify-fixed This issue is likely fixed in new query pipeline. label Nov 5, 2020
@AndriySvyryd
Copy link
Member

Fixed in bca8fa5

@AndriySvyryd AndriySvyryd removed their assignment Sep 21, 2021
@AndriySvyryd AndriySvyryd added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Sep 21, 2021
@AndriySvyryd AndriySvyryd modified the milestones: 6.0.0, 6.0.0-preview1 Sep 21, 2021
@ajcvickers ajcvickers modified the milestones: 6.0.0-preview1, 6.0.0 Nov 8, 2021
@mdhthahmd
Copy link

mdhthahmd commented Dec 18, 2021

The work around fix the exception/error with the ef cli tool, but databse doesnot have the fields as mentioned here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-model-building closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported punted-for-5.0 type-bug
Projects
None yet
Development

No branches or pull requests

5 participants