web-dev-qa-db-ja.com

「IDesignTimeDbContextFactory <DataContext>」の実装をasp.net-core-2.0のプロジェクトに追加する方法

ここに私がインストールしたパッケージのリストがあります: 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());
    }
}
18
M J

編集:現在廃止されました。 Microsoft 移行ドキュメントを更新 9月末に更新方法を示し、この回避策を必要としないようにしました。

このように githubで提起した問題 で、DB初期化コードをプログラムメインに移動し、BuildWebHost()と.Run()の間に配置します。

Mainでvar context = services.GetRequiredService<MyContext>();を使用してDBコンテキストを取得する必要があることを理解すると、比較的簡単になり、すべてが期待どおりに機能します。 (DBの初期化は、プログラムを実行するたびにではなく、1回限りの初期化だとまだ思っていますが)

14
gbjbaanb

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-

5
Srinivas M. P.

私にとっては、コンストラクタインジェクションでDBContextクラスを作成しましたが、このエラーが発生します。それが機能するよりもパラメータのないコンストラクタを持つように戻りました。

1
Dipen Lama

2.0プロジェクトでは、SeedData.InitializeProgram.csMainメソッドの呼び出し:

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

1

最新の.Net Core 2.0.3でも同じ問題が発生しました。 dbContext実装(カスタムインターフェイスIUnitOfWork)を使用した別のプロジェクトがあり、最初は移行が完全に機能しました。しかし、他のインフラストラクチャを実装した後、同様のエラーが発生しました。

タイプ「TestCoreUnitOfWork」のオブジェクトを作成できません。プロジェクトに「IDesignTimeDbContextFactory」の実装を追加するか、設計時にサポートされる追加パターンについて https://go.Microsoft.com/fwlink/?linkid=851728 を参照してください。

実装に関する提案された解決策IDesignTimeDbContextFactoryは問題ありませんが、なぜ以前に移行が機能していたのか疑問に思っていましたか?どのコードの変更が移行を中断したかを知るために、私は数時間を費やしました。結局のところ、ブートストラップの初期化であり、すべての参照アセンブリを(Assembly.Load()経由で)ソリューションからロードしました。すべてのブートストラップを直接呼び出して、これを従来の方法に変更した後、移行が再び機能し始めました。

要約すると、質問に答えるために、移行エラーの原因が考えられます-StartUp.ConfigureServices()Assembly.Load()を使用します。

それが誰かに役立つことを願っています。

1
Pavel K.

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();

今では動作します

0
mkb

問題は、Startup.Configure ...からdbをシードすることにあります。この回避策を使用して、まだ実行できます。テストされ、正常に動作しました

https://garywoodfine.com/how-to-seed-your-ef-core-database/

0
Nick G.

EF 2.0は、プロジェクトの古いネットコアテンプレートから残っている「サンプルデータ」では動作しないようです。次の行をコメントするだけで、このエラーを取り除くことができました。

SampleData.Initialize(app.ApplicationServices);

おもう

var context = serviceProvider.GetService<ApplicationDbContext>();
context.Database.Migrate();

このエラーの場合。この修正が正しいかどうかはわかりませんが、動作します。

0
sibvic

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を実装する必要はありません。

0
Tobias Punke