Working with the DotNetCore solution with a project WebApiand a separate project Datathat hosts the Entity Framework implementation. We update libraries as they become available, so we use all the latest Core materials.
In the project, Datawe created ApplicationDbContextFactoryto create migrations (we need a constructor without parameters). Due to the constructor’s lack of parameters, when adding hyphenation, you cannot enter IOptions<>to easily access values appsettings.json. We have finished using ConfigurationBuilderto pull out files WebApi appsettings.json.
Recently, we changed ApplicationDbContextFactoryto also pull user-secrets. This allows each developer to use a custom connection string without having to ignore the file or remember not to commit something.
Since making this change, use dotnet ef migrations add MIGRATION_NAMEhas worked great on the command line. However, when used add-migration MIGRATION_NAMEin the Visual Studio Package Manager Console, the following error is now displayed:
add-migration: An exception that throws a "Substring" with an argument of "1": "StartIndex cannot be less than zero. Parameter name: startIndex" At line: 1 char: 1 + add-migration TEST + ~~~~~~~~ ~~~~~~~~~~~~~~ + CategoryInfo: NotSpecified: (:) [Add-Migration], MethodInvocationException + FullyQualifiedErrorId: ArgumentOutOfRangeException, Add-Migration
, , , ( ), . , ApplicationDbContextFactory.
, :
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Models.Domain.Settings;
using System;
using System.Diagnostics;
namespace Data
{
public class ApplicationDbContextFactory : IDbContextFactory<ApplicationDbContext>
{
private readonly SolutionSettings _settings;
public ApplicationDbContextFactory()
{
}
public ApplicationDbContextFactory(IOptions<SolutionSettings> settings)
{
_settings = settings.Value;
}
public ApplicationDbContext Create(DbContextFactoryOptions options)
{
if (_settings != null && _settings.DbConnection != null)
{
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseSqlServer(_settings.DbConnection, opts => {
opts.EnableRetryOnFailure();
opts.MigrationsAssembly("Data");
});
return new ApplicationDbContext(optionsBuilder.Options);
}
else
{
return Create(options.ContentRootPath, options.EnvironmentName);
}
}
private ApplicationDbContext Create(string basePath, string environmentName)
{
basePath = basePath.Replace("Data", "WebApi");
Console.Write($"PATH & ENV: {basePath}, {environmentName}" + Environment.NewLine);
var builder = new ConfigurationBuilder()
.SetBasePath(basePath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{environmentName.ToLower()}.json", optional: true, reloadOnChange: true)
.AddUserSecrets("USER_SECRETS_ID")
.AddEnvironmentVariables();
var config = builder.Build();
var connectionString = config["SolutionSettings:DbConnection"];
Console.Write($"CONNECTION STRING: {connectionString}" + Environment.NewLine);
return Create(connectionString);
}
private ApplicationDbContext Create(string connectionString)
{
if (string.IsNullOrEmpty(connectionString))
throw new ArgumentException(
$"{nameof(connectionString)} is null or empty.",
nameof(connectionString));
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseSqlServer(connectionString, options => {
options.EnableRetryOnFailure();
options.MigrationsAssembly("Data");
});
return new ApplicationDbContext(optionsBuilder.Options);
}
}
}
; opts.EnableRetryOnFailure(); opts.MigrationsAssembly("Data");, , - .
:
- RC Core . ? factory :
- - , Visual Studio?