EF Core - Connection string cannot be null

2019-08-31 12:25发布

问题:

I am using ASP.Net Core 2.1 with EF Core 2.1

While running any Migration from PMC, I am getting the below error

Value cannot be null. Parameter name: connectionString

This is how my Context class looks like

public class MyAppContextFactory : IDesignTimeDbContextFactory<MyAppContext>
{
    private readonly string _dbConnection;

    public MyAppContextFactory()
    {

    }
    public MyAppContextFactory(string dbConnection)
        : this()
    {
        _dbConnection = dbConnection;

    }

    public MyAppContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<MyAppContext>();
        optionsBuilder.UseSqlServer(_dbConnection, opts => opts.CommandTimeout((int)TimeSpan.FromMinutes(15).TotalSeconds));
        return new MyAppContext(optionsBuilder.Options);
    }


}

My Connection string is present in API layer in appsettings.json & as good practice I should not add any reference to EF in API/UI layer.

How do I set the connection string as per environment in such layered architecture?

Thanks.

回答1:

EF actually starts your application to generate migration as of 2.0 I think. You need to add DesignTimeDbContextFactory to your project that will query the connection string for this use case, e.g. like this:

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<StorageContext>
    {
        public StorageContext CreateDbContext(string[] args)
        {
            IConfigurationRoot configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false)
                .AddJsonFile("appsettings.Development.json", optional: true)
                .Build();

            var builder = new DbContextOptionsBuilder<StorageContext>();
            var connectionString = configuration.GetConnectionString("DefaultConnection");
            builder.UseSqlServer(connectionString);

            Console.WriteLine($"Running DesignTime DB context. ({connectionString})");

            return new StorageContext(builder.Options);
        }
    }