Efcore: Unable to create migrations after upgrading from EF Core 2.0 to 2.1

Created on 11 Jun 2018  路  20Comments  路  Source: dotnet/efcore

Describe what is not working as expected.
dotnet ef migrations list command throws an error after upgrading from dotnet core 2.0 to 2.1 and ef core 2.1

If you are seeing an exception, include the full exceptions details (message and stack trace).

An error occurred while accessing the IWebHost on class 'Program'. Continuing wi
thout the application service provider. Error: Value cannot be null.
Parameter name: configuration
Unable to create an object of type 'xxx'. Add an implementation of
'IDesignTimeDbContextFactory' to the project, or see https://g
o.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at desig
n time.

Exception message:
An error occurred while accessing the IWebHost on class 'Program'. Continuing wi
thout the application service provider. Error: Value cannot be null.
Parameter name: configuration
Unable to create an object of type 'xxx'. Add an implementation of
'IDesignTimeDbContextFactory<xxx>' to the project, or see https://g
o.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at desig
n time.
Stack trace:

Steps to reproduce

Include a complete code listing (or project/solution) that we can run to reproduce the issue.

Partial code listings, or multiple fragments of code, will slow down our response or cause us to push the issue back to you to provide code to reproduce the issue.

```c#
BuildWebHost(args).Run() was replaced with

CreateWebHostBuilder(args)
.Build()
.Run();

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup();
```

Further technical details

EF Core version: 2.1
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 7
IDE: Visual Studio 2017 15.7.3

closed-question customer-reported

Most helpful comment

@Tarig0 With 2.1, either CreateWebHostBuilder or BuildWebHost can be used--see https://github.com/aspnet/EntityFrameworkCore/pull/10100

@narind3rs The problem is that when EF calls either CreateWebHostBuilder or BuildWebHost it does so without running Main. (This is intentional because EF needs to build the model and use the DbContext without starting the application.) This means that when EF invokes on of these methods the static IConfiguration property is still null--since it is only set in Main. So, you'll need to either make sure that IConfiguration is set/handled when EF calls one of these methods, or use IDesignTimeDbContextFactory.

All 20 comments

Looking at the error it looks like it will ONLY match an IWebHost property and you only have the IWebHostBuilder

An error occurred while accessing the ***IWebHost*** on class 'Program'

The issue is here
c# public static IWebHost /* not the builder */ BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); // this needs to be here

Wait a minute, can you validate you EF Core version? Looks like you are running 2.0 still

Here's the ef core version

Entity Framework Core .NET Command-line Tools
2.1.0-rtm-30799

Hmmmm, what's your proj file say?

<PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="4.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.ResponseCaching" Version="2.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.1.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.0" />

can you paste your full program.cs?

```c#

using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using Serilog.Events;

namespace Tracker.App
{
public class Program
{
private static IConfiguration Configuration;
public static void Main(string[] args)
{
var currentEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

        Configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{currentEnv}.json", optional: true)
            .AddEnvironmentVariables()
            .Build();

        try
        {

            CreateWebHostBuilder(args)
                .Build()
                .Run();

            Log.Information("Web Host Started.");
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated.");
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseSerilog(new LoggerConfiguration()
                .ReadFrom.Configuration(Configuration)
                .MinimumLevel.Information()
                .MinimumLevel.Override("Microsoft", LogEventLevel.Debug)
                //.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Error)
                .Enrich.FromLogContext()
                .Enrich.WithMachineName()
                .Enrich.WithEnvironmentUserName()
                .Enrich.WithThreadId()
                .WriteTo.MSSqlServer(Configuration.GetSection("ConnectionStrings:SqlDbConn").Value,
                                    "AppLogs",
                                    restrictedToMinimumLevel: LogEventLevel.Warning,
                                    batchPostingLimit: 100,
                                    autoCreateSqlTable: true)
                .CreateLogger())
            .UseStartup<Startup>();

}

}

```

```c#
using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

namespace Tracker.App
{
public class Program
{
public static void Main(string[] args)
{
try
{
CreateWebHostBuilder(args).Build().Run();
Log.Information("Web Host Started.");
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated.");
}
finally
{
Log.CloseAndFlush();
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup();
}
}
```

how does that fair? I know I took out the logger but this is to test

No, that doesn't help. I get the exact same error.

I am able to get past the issue by introducing the code below:

```c#
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory
{
public xxCtx CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
//.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.Build();

        var builder = new DbContextOptionsBuilder<xxCtx>();

        var connStr = configuration.GetConnectionString("SqlDbConn");

        builder.UseSqlServer(connStr, 
            b => b.MigrationsAssembly("xxx"));

        return new xxCtx(builder.Options);

    }
}

This wasn't required in ef core 2.0.  I still get the warning below:

```c#

An error occurred while accessing the IWebHost on class 'Program'. Continuing wi
thout the application service provider. Error: Value cannot be null.
Parameter name: configuration

but at least the migrations are working.

@Tarig0 Thank you for your help so far!

I am hoping there's a better solution for this issue.

Could you switch to the meta nuget package asp.net core all? I think the issue may be in your version of Microsoft.AspNetCore.Hosting

Added the aspnetcore.all package but that doesn't help either.

<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="4.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.ResponseCaching" Version="2.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.1.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.0" />
    <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
    <PackageReference Include="Serilog.Enrichers.Environment" Version="2.1.2" />
    <PackageReference Include="Serilog.Enrichers.Thread" Version="3.0.0" />
    <PackageReference Include="Serilog.Settings.Configuration" Version="2.6.1" />
    <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
    <PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />
    <PackageReference Include="Serilog.Sinks.MSSqlServer" Version="5.1.2" />
    <PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.0" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="2.5.0" />
  </ItemGroup>

Unfortunately I still get the same error and warning.

```c#
An error occurred while accessing the IWebHost on class 'Program'. Continuing wi
thout the application service provider. Error: Value cannot be null.
Parameter name: configuration
Unable to create an object of type 'xx'. Add an implementation of
'IDesignTimeDbContextFactory' to the project, or see https://g
o.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at desig
n time.

```

Yea that looks right, try the following 2.0 format for the program class

c# public static IWebHost /* not the builder */ BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); //move the build here this is the old format

@Tarig0 With 2.1, either CreateWebHostBuilder or BuildWebHost can be used--see https://github.com/aspnet/EntityFrameworkCore/pull/10100

@narind3rs The problem is that when EF calls either CreateWebHostBuilder or BuildWebHost it does so without running Main. (This is intentional because EF needs to build the model and use the DbContext without starting the application.) This means that when EF invokes on of these methods the static IConfiguration property is still null--since it is only set in Main. So, you'll need to either make sure that IConfiguration is set/handled when EF calls one of these methods, or use IDesignTimeDbContextFactory.

Ah that's where the null error is coming from, yea @narind3rs you should be doing the use function inside your startup class, if at all possible

@Tarig0 @ajcvickers Thank You Both!

As a note for the next guy who may stumble here.

$env:ASPNETCORE_ENVIRONMENT='Development'
try setting your env variable before running the add-migration

@Tarig0 With 2.1, either CreateWebHostBuilder or BuildWebHost can be used--see #10100

@narind3rs The problem is that when EF calls either CreateWebHostBuilder or BuildWebHost it does so without running Main. (This is intentional because EF needs to build the model and use the DbContext without starting the application.) This means that when EF invokes on of these methods the static IConfiguration property is still null--since it is only set in Main. So, you'll need to either make sure that IConfiguration is set/handled when EF calls one of these methods, or use IDesignTimeDbContextFactory.

Can someone please post the final solution. I have a rough idea, however, I am not able to figure out where to initialize the IConfiguration property exactly.

Just got mine working. Here is my CreateWebHostBuilder method. Set the IConfiguration property in the ConfigureAppConfiguration method. Make sure your ASPNETCORE_ENVIRONMENT environment variable is set before using the EF tools. See the comment by @StevenTCramer above.

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost
            .CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((context, config) =>
            {
                config
                    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: false, reloadOnChange: true);
               context.Configuration = config.Build();
            })
            .UseSerilog((context, config) =>
            {
                config
                    .WriteTo.Console()
                    .WriteTo.Seq(context.Configuration.GetValue<string>(ConfigurationKeys.SeqUrl))
                    .Enrich.FromLogContext()
                    .Enrich.WithProperty("Application", Assembly.GetExecutingAssembly().FullName);
            })
            .UseStartup<Startup>()
            .UseIISIntegration();

Setting the ASPNETCORE_ENVIRONMENT to Development works like a charm. As I have different different environment appsettings, I was using a profile whose ASPNETCORE_ENVIRONMENT was not set to development.
Or, as a work around, I had to switch the startup profile to whatever with ASPNETCORE_ENVIRONMENT Development.

Was this page helpful?
0 / 5 - 0 ratings