ここに私がインストールしたパッケージのリストがあります: Installed Packages
Entityframeworkコア2.0を使用しています。エンティティフレームワークコードの最初の移行(add-migrationおよびupdate-databaseコマンド)を使用して初めてデータベースを正常に作成しました。エンティティを更新して移行を実行しようとすると、次のエラーが発生します。
タイプ 'DataContext'のオブジェクトを作成できません。プロジェクトに「IDesignTimeDbContextFactory」の実装を追加するか、設計時にサポートされる追加パターンについて https://go.Microsoft.com/fwlink/?linkid=851728 を参照してください。
ここに私のコードがあります...
Program.cs
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
Startup.cs
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Repositories
services.AddMvc();
services.AddDbContextPool<DataContext>(
options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
//options => options.UseSqlServer(@"Server=LAPTOP-518D8067;Database=Gyanstack;Trusted_Connection=True;MultipleActiveResultSets=true"));
services.AddCors();
services.AddScoped<ISectionRepository, SectionRepository>();
services.AddScoped(typeof(IEntityBaseRepository<>), typeof(EntityBaseRepository<>));
}
DataContext.cs
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> options)
: base(options)
{ }
public DbSet<Section> Section { get; set; }
public DbSet<SubSection> SubSection { get; set; }
public DbSet<Article> Article { get; set; }
public DbSet<Comment> Comment { get; set; }
public DbSet<User> User { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.AddConfiguration(new SectionMap());
modelBuilder.AddConfiguration(new SubSectionMap());
modelBuilder.AddConfiguration(new ArticleMap());
modelBuilder.AddConfiguration(new CommentMap());
}
}
編集:現在廃止されました。 Microsoft 移行ドキュメントを更新 9月末に更新方法を示し、この回避策を必要としないようにしました。
このように githubで提起した問題 で、DB初期化コードをプログラムメインに移動し、BuildWebHost()と.Run()の間に配置します。
Mainでvar context = services.GetRequiredService<MyContext>();
を使用してDBコンテキストを取得する必要があることを理解すると、比較的簡単になり、すべてが期待どおりに機能します。 (DBの初期化は、プログラムを実行するたびにではなく、1回限りの初期化だとまだ思っていますが)
Program.csを変更しただけ
これから
public class Program
{
public static void Main(string[] args)
{
var Host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
Host.Run();
}
}
これに
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
ソース: https://wildermuth.com/2017/07/06/Program-cs-in-ASP-NET-Core-2-
私にとっては、コンストラクタインジェクションでDBContextクラスを作成しましたが、このエラーが発生します。それが機能するよりもパラメータのないコンストラクタを持つように戻りました。
2.0プロジェクトでは、SeedData.Initialize
Program.csのMain
メソッドの呼び出し:
var Host = BuildWebHost(args);
using (var scope = Host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
SeedData.Initialize(services, "").Wait();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
Host.Run();
参照: https://docs.Microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#move-database-initialization-code
最新の.Net Core 2.0.3でも同じ問題が発生しました。 dbContext実装(カスタムインターフェイスIUnitOfWork)を使用した別のプロジェクトがあり、最初は移行が完全に機能しました。しかし、他のインフラストラクチャを実装した後、同様のエラーが発生しました。
タイプ「TestCoreUnitOfWork」のオブジェクトを作成できません。プロジェクトに「IDesignTimeDbContextFactory」の実装を追加するか、設計時にサポートされる追加パターンについて https://go.Microsoft.com/fwlink/?linkid=851728 を参照してください。
実装に関する提案された解決策IDesignTimeDbContextFactoryは問題ありませんが、なぜ以前に移行が機能していたのか疑問に思っていましたか?どのコードの変更が移行を中断したかを知るために、私は数時間を費やしました。結局のところ、ブートストラップの初期化であり、すべての参照アセンブリを(Assembly.Load()経由で)ソリューションからロードしました。すべてのブートストラップを直接呼び出して、これを従来の方法に変更した後、移行が再び機能し始めました。
要約すると、質問に答えるために、移行エラーの原因が考えられます-StartUp.ConfigureServices()でAssembly.Load()を使用します。
それが誰かに役立つことを願っています。
Npgsql.EntityFrameworkCore.PostgreSQLを使用しているときにこの問題に遭遇しました(重要な場合)
考慮に入れる https://docs.Microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#add-configuration-providers
これをBuildWebHost()に追加しました
.ConfigureAppConfiguration((hostContext, config) =>
{
// delete all default configuration providers
config.Sources.Clear();
config.AddJsonFile("appsettings.json", optional: true);
})
だからそれはバカム:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((hostContext, config) =>
{
// delete all default configuration providers
config.Sources.Clear();
config.AddJsonFile("appsettings.json", optional: true);
})
.Build();
今では動作します
問題は、Startup.Configure ...からdbをシードすることにあります。この回避策を使用して、まだ実行できます。テストされ、正常に動作しました
EF 2.0は、プロジェクトの古いネットコアテンプレートから残っている「サンプルデータ」では動作しないようです。次の行をコメントするだけで、このエラーを取り除くことができました。
SampleData.Initialize(app.ApplicationServices);
おもう
var context = serviceProvider.GetService<ApplicationDbContext>();
context.Database.Migrate();
このエラーの場合。この修正が正しいかどうかはわかりませんが、動作します。
Startup.csクラスを変更する必要があると言う人もいますが、私は何もしませんでした。私のProgram.csクラスを少し変更しただけです
----------古いファイル--------------
public class Program
{
public static void Main(string[] args)
{
var Host = CreateWebHostBuilder(args).Build();
using (var scope = Host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<MvcMovieContext>();
context.Database.Migrate();
SeedData.Initialize(services);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
Host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
----------新しいファイル---------
public static void Main(string[] args)
{
var Host = BuildWebHost(args);
using (var scope = Host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var dbContext = scope.ServiceProvider.GetService<MvcMovieContext>();
//SeeData is a class in my Models folder
SeedData.Initialize(services);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
Host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
これは、.NET Core 2.0の新しいinitプロセスに関連しており、構成の処理方法が異なります(詳細 here )。
1.xからアップグレードした場合は、Program.cs
およびStartup.cs
:
public class Program
{
public static void Main(String[] args)
{
Program.BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(String[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.UseUrls("http://*:8000")
.UseStartup<Startup>()
.Build();
}
public class Statup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
........
}
この変更後、移行は機能するはずであり、IDesignTimeDbContextFactory
を実装する必要はありません。