如何在asp.net-core-2.0中为项目添加'IDesignTimeDbContextFactory <datacontext>'的实现

时间:2017-08-26 05:45:03

标签: c# entity-framework-core 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());
    }
}

11 个答案:

答案 0 :(得分:14)

编辑:现在已经过时了。 9月底的Microsoft updated their migration document将显示如何更新,因此您不需要此解决方法。

如此issue I raised on github所示,您将数据库初始化代码移至Program main,将其置于BuildWebHost()和.Run()之间

一旦你理解了你需要使用DB上下文,它相对容易 在Main中var context = services.GetRequiredService<MyContext>();,然后一切按预期工作。 (虽然我仍然认为数据库初始化是一次性的初始化,而不是每个程序运行的东西)

答案 1 :(得分:5)

只需更改我的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-0

答案 2 :(得分:1)

在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

答案 3 :(得分:1)

对我来说,我使用构造函数注入制作了我的DBContext类,它给出了此错误。我恢复使用无参数的构造函数。

答案 4 :(得分:0)

问题在于从Startup.Configure播种数据库......你仍然可以通过这种方法来完成它。经过测试和工作正常

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

答案 5 :(得分:0)

看起来EF 2.0不适用于“样本数据”,它仍然来自项目的旧网络核心模板。 我设法摆脱了这个错误只是评论下一行:

SampleData.Initialize(app.ApplicationServices);

我认为

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

出现此错误。我不确定这个修复是否正确但是有效。

答案 6 :(得分:0)

这与.NET Core 2.0的新init进程有关,其中配置的处理方式不同(详情here)。

如果您从1.x升级,请修改您的Program.csStartup.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的实施。

答案 7 :(得分:0)

我在使用Npgsql.EntityFrameworkCore.PostgreSQL时遇到此错误,如果重要的话。

考虑到 https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#add-configuration-providers

我将此添加到BuildWebHost()

class Auth:
    BASE_URL = 'http.............'

    def auth(self):
        params = {
            'user': u'g1625719',
            'pass': u'472001',
            'from_site': 1,
            'dev': u'16e753be3dc097354e3328e47c3701a9'
        }
        session = requests.Session()
        url = self.BASE_URL + 'api/v1/login/auth?info=1'
        r = session.post(url, params)
        print(r.text)

    def get_url(self):
        url = self.BASE_URL + '#!/line/cart/checklist/'
        print(url)
        response = urllib.request.urlopen(url)
        return response.read()

    def parse(self):
        soup = BeautifulSoup(self.get_url(), 'html.parser')
        table = soup.body.find_all('div', {'class': 'example-animate-container'})
        print(table)

所以它标榜:

.ConfigureAppConfiguration((hostContext, config) =>
{
    // delete all default configuration providers
    config.Sources.Clear();
    config.AddJsonFile("appsettings.json", optional: true);
})

现在可行了

答案 8 :(得分:0)

有些人说您必须更改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();
}

答案 9 :(得分:0)

[对于2.1.1版]

我在 MyDbContext.cs 中添加了OnConfiguring方法:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
 optionsBuilder.UseSqlServer(@"Server(localdb)\\mssqllocaldb;Database=MyDataBase;Trusted_Connection=True;MultipleActiveResultSets=truer");
}

答案 10 :(得分:0)

因此,首先您必须创建一个默认构造函数,然后添加这个包 Microsoft.EntityFrameworkCore.Design 它将开始工作。