efcore: Exception when applying database migrations containing spatial data

Applying Entity Framework Core migrations with the 2.2.0 previews (and spatial extensions) does not work.

Exception message:

Object reference not set to an instance of an object.

Stack trace:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.GetColumnType(String schema, String table, String name, Type clrType, Nullable`1 unicode, Nullable`1 maxLength, Nullable`1 fixedLength, Boolean rowVersion, IModel model)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.ColumnDefinition(String schema, String table, String name, Type clrType, String type, Nullable`1 unicode, Nullable`1 maxLength, Nullable`1 fixedLength, Boolean rowVersion, Boolean nullable, Object defaultValue, String defaultValueSql, String computedColumnSql, IAnnotatable annotatable, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.ColumnDefinition(String schema, String table, String name, Type clrType, String type, Nullable`1 unicode, Nullable`1 maxLength, Nullable`1 fixedLength, Boolean rowVersion, Boolean nullable, Object defaultValue, String defaultValueSql, String computedColumnSql, Boolean identity, IAnnotatable annotatable, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.ColumnDefinition(String schema, String table, String name, Type clrType, String type, Nullable`1 unicode, Nullable`1 maxLength, Nullable`1 fixedLength, Boolean rowVersion, Boolean nullable, Object defaultValue, String defaultValueSql, String computedColumnSql, IAnnotatable annotatable, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.ColumnDefinition(AddColumnOperation operation, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(CreateTableOperation operation, IModel model, MigrationCommandListBuilder builder, Boolean terminate)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.Generate(CreateTableOperation operation, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(IReadOnlyList`1 operations, IModel model)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.Generate(IReadOnlyList`1 operations, IModel model)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.GenerateUpSql(Migration migration)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

Edit:

After trying to update the database with verbose mode enabled we can see a bit better what’s going on:

Using project 'C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\ConsoleApp3.csproj'.
Using startup project 'C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\ConsoleApp3.csproj'.
Writing 'C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\obj\ConsoleApp3.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\corstian\AppData\Local\Temp\tmpE575.tmp /verbosity:quiet /nologo C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\ConsoleApp3.csproj
Writing 'C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\obj\ConsoleApp3.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\corstian\AppData\Local\Temp\tmpEBCF.tmp /verbosity:quiet /nologo C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\ConsoleApp3.csproj
dotnet build C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\ConsoleApp3.csproj /verbosity:quiet /nologo

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:02.00
dotnet exec --depsfile C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\bin\Debug\netcoreapp2.1\ConsoleApp3.deps.json --additionalprobingpath C:\Users\corstian\.nuget\packages --additionalprobingpath "C:\Program Files\dotnet\sdk\NuGetFallbackFolder" --runtimeconfig C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\bin\Debug\netcoreapp2.1\ConsoleApp3.runtimeconfig.json "C:\Program Files\dotnet\sdk\2.2.100-preview1-009349\DotnetTools\dotnet-ef\2.2.0-preview1-35029\tools\netcoreapp2.2\any\tools\netcoreapp2.0\any\ef.dll" database update --assembly C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\bin\Debug\netcoreapp2.1\ConsoleApp3.dll --startup-assembly C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\bin\Debug\netcoreapp2.1\ConsoleApp3.dll --project-dir C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\ --language C# --working-dir C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3 --verbose --root-namespace ConsoleApp3
Using assembly 'ConsoleApp3'.
Using startup assembly 'ConsoleApp3'.
Using application base 'C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\bin\Debug\netcoreapp2.1'.
Using working directory 'C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3'.
Using root namespace 'ConsoleApp3'.
Using project directory 'C:\Users\corstian\source\repos\ConsoleApp3\ConsoleApp3\'.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider...
Finding IWebHost accessor...
No CreateWebHostBuilder(string[]) method was found on type 'ConsoleApp3.Program'.
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext 'BugDbContext'.
Using context 'BugDbContext'.
Finding design-time services for provider 'Microsoft.EntityFrameworkCore.SqlServer'...
Using design-time services from provider 'Microsoft.EntityFrameworkCore.SqlServer'.
Finding design-time services referenced by assembly 'ConsoleApp3'.
No referenced design-time services were found.
Finding IDesignTimeServices implementations in assembly 'ConsoleApp3'...
No design-time services were found.
Migrating using database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opening connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opened connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Closing connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Closed connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opening connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opened connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Executed DbCommand (194ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Closing connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Closed connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opening connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opened connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Closing connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Closed connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opening connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opened connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Executed DbCommand (107ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Closing connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Closed connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opening connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Opened connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [MigrationId], [ProductVersion]
FROM [__EFMigrationsHistory]
ORDER BY [MigrationId];
Executed DbCommand (26ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [MigrationId], [ProductVersion]
FROM [__EFMigrationsHistory]
ORDER BY [MigrationId];
A data reader was disposed.
Closing connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Closed connection to database 'EFCoreSpatialBugRepro' on server '(localdb)\.'.
Applying migration '20180910172233_0.1'.
'BugDbContext' disposed.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.GetColumnType(String schema, String table, String name, Type clrType, Nullable`1 unicode, Nullable`1 maxLength, Nullable`1 fixedLength, Boolean rowVersion, IModel model)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.ColumnDefinition(String schema, String table, String name, Type clrType, String type, Nullable`1 unicode, Nullable`1 maxLength, Nullable`1 fixedLength, Boolean rowVersion, Boolean nullable, Object defaultValue, String defaultValueSql, String computedColumnSql, IAnnotatable annotatable, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.ColumnDefinition(String schema, String table, String name, Type clrType, String type, Nullable`1 unicode, Nullable`1 maxLength, Nullable`1 fixedLength, Boolean rowVersion, Boolean nullable, Object defaultValue, String defaultValueSql, String computedColumnSql, Boolean identity, IAnnotatable annotatable, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.ColumnDefinition(String schema, String table, String name, Type clrType, String type, Nullable`1 unicode, Nullable`1 maxLength, Nullable`1 fixedLength, Boolean rowVersion, Boolean nullable, Object defaultValue, String defaultValueSql, String computedColumnSql, IAnnotatable annotatable, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.ColumnDefinition(AddColumnOperation operation, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(CreateTableOperation operation, IModel model, MigrationCommandListBuilder builder, Boolean terminate)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.Generate(CreateTableOperation operation, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(IReadOnlyList`1 operations, IModel model)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.Generate(IReadOnlyList`1 operations, IModel model)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.GenerateUpSql(Migration migration)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Object reference not set to an instance of an object.

Steps to reproduce

  • Create new .NET Standard project.
  • Alter the project file to be able to run migrations. (Involves adding netcoreapp2.2 to the TargetFrameworks thingy in the project file.
  • Add migrations through EF Core tooling by running dotnet ef migrations add 0.1
  • Try to apply said migrations to the database by running dotnet ef database update

Please note that I have been using the 2.2.0-preview2-35148 packages as there have been problems resolving the System.Data.SqlClient dependency on later versions.

For a minimalistic demo project showing the set up for reproducing this bug; see: https://github.com/corstian/efcore-migrations-spatial-bug-reproduction.

Migrations have been generated. Running dotnet ef database update should trigger said bug.

Further technical details

EF Core version: 2.2.0-preview-26820-02 Database Provider: Microsoft.EntityFrameworkCore.SqlServer Operating system: Windows 10 Pro Version: 10.0.17134 Build 17134

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 19 (8 by maintainers)

Most upvoted comments

The modelbuilder for entities with spatial data, which is generated with the migrations, contain the following configuration:

b.Property<SqlBytes>("Location");

Changing this into the following (or whatever specific spatial type you’re using) in all your auto-generated migration files:

b.Property<Point>("Location");

Will make it work correctly!

installed preview 3 for the first time, added a Point property on my model class, and generated the migration.

That is exactly something not supported fully. You can create migration after installing preview package and try it out but once RTM is released, you should install RTM package and recreate migrations which were generated using preview package.

We should still look in to the exception, but does it work if you add a class like this to your project?

class MyDesignTimeServices : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection services)
        => services.AddEntityFrameworkSqlServerNetTopologySuite();
}