Efcore: Scaffolding Migrations programmatically in Asp.Net Core 5 and EF Core 5

Created on 6 Dec 2020  路  6Comments  路  Source: dotnet/efcore

I'm trying to scaffold migration files by Internal EF Core APIs programmatically. But I get:

System.NullReferenceException: 'Object reference not set to an instance of an object.'

from ScaffoldMigration method and nothing is NULL as u can see below.

image

and what's alternative for this
new Microsoft.EntityFrameworkCore.SqlServer.Design.Internal.SqlServerDesignTimeServices().ConfigureDesignTimeServices(designTimeServiceCollection);

because in below screenshot shows a green underline and says

It may be changed or removed without notice in any release

image

thanx for helping :)

EF Core version: 5.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: ASP.NET Core 5.0
Operating system: Windows 10
IDE: Visual Studio 2019 Preview _latest_

closed-question customer-reported

All 6 comments

Remove the AddSingleton calls for MigraitonsScaffolder and its dependencies.

Here's the non-Internal way to access SqlServerDesignTimeServices:

var providerAssembly = Assembly.Load("Microsoft.EntityFrameworkCore.SqlServer");
var providerServicesAttribute = providerAssembly.GetCustomAttribute<DesignTimeProviderServicesAttribute>();
var providerServicesType = providerAssembly.GetType(providerServicesAttribute.TypeName);
var providerServices = (IDesignTimeServices)Activator.CreateInstance(providerServicesType);
providerServices.ConfigureDesignTimeServices(services);

If you still encounter errors after that, can you attach a runnable repro so we can debug further?

here is my modified code :
var designTimeServiceCollection = new ServiceCollection(); var providerAssembly = Assembly.Load("Microsoft.EntityFrameworkCore.SqlServer"); var providerServicesAttribute = providerAssembly.GetCustomAttribute<DesignTimeProviderServicesAttribute>(); var providerServicesType = providerAssembly.GetType(providerServicesAttribute.TypeName); var providerServices = (IDesignTimeServices)Activator.CreateInstance(providerServicesType); providerServices.ConfigureDesignTimeServices(designTimeServiceCollection); var designTimeServices = designTimeServiceCollection.BuildServiceProvider(); var scaffolder = designTimeServices.GetRequiredService<MigrationsScaffolder>();
but last line when getting MigrationsScaffolder from the services gives error and says there is no MigrationsScaffolder registered because I removed the AddSingleton calls for MigrationsScaffolder .

can u show me the complete code of getting MigrationsScaffolder from DesignTimeServices or anywhere ?

Thanx :)

Services are registered under their interface. Use IMigrationsScaffolder

how can I use IMigrationsScaffolder ? I mean how to get it or initiate this interface ?
I Searched everywhere but could not find a documentation on that.

Thanx :)

Here's the code listing from our docs: (Note, you don't need SqlServerDesignTimeServices for Migrations)

var db = new MyDbContext();

// Create design-time services
var serviceCollection = new ServiceCollection();
serviceCollection.AddEntityFrameworkDesignTimeServices();
serviceCollection.AddDbContextDesignTimeServices(db);
var serviceProvider = serviceCollection.BuildServiceProvider();

// Add a migration
var migrationsScaffolder = serviceProvider.GetService<IMigrationsScaffolder>();
var migration = migrationsScaffolder.ScaffoldMigration(migrationName, rootNamespace);
migrationsScaffolder.Save(projectDir, migration, outputDir);

Thank you very much.
That was what I need

Regards ;)

Was this page helpful?
0 / 5 - 0 ratings