Skip to content

InvalidOperationException when creating a migration and using HasData in OnModelCreating #17145

@stevejgordon

Description

@stevejgordon

I'm hitting an exception when creating a new migration on a DbContext which overrides OnModelCreating and includes HasData. I experienced this in an existing project which has been updated from 2,2 although I was able to reproduce the flow of events using a newly created ASP.NET Core 3.0 project.

Steps to reproduce

  1. Start with a default ASP.NET Core project which uses Identity
  2. Add a simple DbSet, I used...
public class ApplicationDbContext : IdentityDbContext
{
	public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
		: base(options)
	{
	}

	public DbSet<Thing> Things { get; set; }      

	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		modelBuilder.Entity<Thing>()
			.HasData(new Thing { Id = 1, Name = "A thing" });

		base.OnModelCreating(modelBuilder);
	}
}

public class Thing
{
	public int Id { get; set; }
	public string Name { get; set; }
}
  1. Create a migration which should succeed
  2. Add another DbSet...
public class ApplicationDbContext : IdentityDbContext
{
	public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
		: base(options)
	{
	}

	public DbSet<Thing> Things { get; set; }
	public DbSet<AnotherThing> AnotherThings { get; set; }

	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		modelBuilder.Entity<Thing>()
			.HasData(new Thing { Id = 1, Name = "A thing" });

		base.OnModelCreating(modelBuilder);
	}
}

public class Thing
{
	public int Id { get; set; }
	public string Name { get; set; }
}

public class AnotherThing
{
	public int Id { get; set; }
	public string Name { get; set; }
}
  1. Try to create a migration

The expected result is that a new migration is generated.
The actual result is an exception...

C:\Users\steve.gordon\source\repos\WebApplication3\WebApplication3>dotnet ef migrations add step3
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.0.0-preview8.19405.11 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.InvalidOperationException: The model must be finalized before 'GetTypeMapping' can be used. Ensure that either 'OnModelCreating' has completed or, if using a stand-alone 'ModelBuilder', that 'FinalizeModel' has been called.
   at Microsoft.EntityFrameworkCore.PropertyExtensions.GetTypeMapping(IProperty property)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SimplePrincipalKeyValueFactory`1..ctor(IProperty property)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.KeyValueFactoryFactory.CreateSimpleFactory[TKey](IKey key)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.KeyValueFactoryFactory.Create[TKey](IKey key)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Key.<>c__19`1.<GetPrincipalKeyValueFactory>b__19_0(Key k)
   at Microsoft.EntityFrameworkCore.Internal.NonCapturingLazyInitializer.EnsureInitialized[TParam,TValue](TValue& target, TParam param, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Key.GetPrincipalKeyValueFactory[TKey]()
   at Microsoft.EntityFrameworkCore.Metadata.Internal.KeyExtensions.GetPrincipalKeyValueFactory[TKey](IKey key)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMapFactoryFactory.CreateFactory[TKey](IKey key)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMapFactoryFactory.Create(IKey key)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Key.<>c.<get_IdentityMapFactory>b__18_0(Key k)
   at Microsoft.EntityFrameworkCore.Internal.NonCapturingLazyInitializer.EnsureInitialized[TParam,TValue](TValue& target, TParam param, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Key.get_IdentityMapFactory()
   at Microsoft.EntityFrameworkCore.Metadata.Internal.KeyExtensions.GetIdentityMapFactory(IKey key)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.GetOrCreateIdentityMap(IKey key)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable`1 forceStateWhenUnknownKey)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.Microsoft.EntityFrameworkCore.Update.IUpdateEntry.set_EntityState(EntityState value)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.TrackData(IModel source, IModel target)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Diff(IModel source, IModel target, DiffContext diffContext)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.GetDifferences(IModel source, IModel target)
   at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language)
   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)
Exception has been thrown by the target of an invocation.

Further technical details

EF Core version: 3.0.0-preview8.19405.7 (although also tried with a nightly build of preview 9)
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10
IDE: Visual Studio 2019 16.3 Preview 2.0

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions