20

升级到ASP.NET Core 2.0后,似乎无法再创建迁移。升级到ASP.NET Core 2.0后无法创建迁移

我越来越

"An error occurred while calling method 'BuildWebHost' on class 'Program'. Continuing without the application service provider. Error: One or more errors occurred. (Cannot open database "..." requested by the login. The login failed. Login failed for user '...'"

"Unable to create an object of type 'MyContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time."

我以前运行是$ dotnet ef migrations add InitialCreate --startup-project "..\Web"(从与的DbContext项目/文件夹)的命令。

连接字符串:"Server=(localdb)\\mssqllocaldb;Database=database;Trusted_Connection=True;MultipleActiveResultSets=true"

这是我的Program.cs

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     BuildWebHost(args).Run(); 
    } 

    public static IWebHost BuildWebHost(string[] args) => 
     WebHost.CreateDefaultBuilder(args) 
      .UseStartup<Startup>() 
      .Build(); 
} 
+1

问题可能不在Program.cs中。这可能是使用指令在Configure方法的末尾加载种子数据: DbInitializer.Initialize(context); 如果您有该指令,请对其进行注释: //DbInitializer.Initialize(context); 然后运行迁移说明进行测试。如果问题出现,请继续DbInitializer.cs类。 –

+0

是另一个类库项目中的MyContext类吗? – Orhun

+0

这里同样的问题,上下文在其他库中。如果id在上下文中添加一个参数less consturctor,则migrations正在工作,但是会出现相同的错误:(在'Program'类中调用方法'BuildWebHost'时发生错误,继续执行没有应用程序服务提供程序错误:未设置对象引用到一个对象的实例。 ) – iBoonZ

回答

30

您可以在您的Web项目中添加一个实现IDesignTimeDbContextFactory的类。

下面是示例代码:

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<CodingBlastDbContext> 
{ 
    public CodingBlastDbContext CreateDbContext(string[] args) 
    { 
     IConfigurationRoot configuration = new ConfigurationBuilder() 
      .SetBasePath(Directory.GetCurrentDirectory()) 
      .AddJsonFile("appsettings.json") 
      .Build(); 
     var builder = new DbContextOptionsBuilder<CodingBlastDbContext>(); 
     var connectionString = configuration.GetConnectionString("DefaultConnection"); 
     builder.UseSqlServer(connectionString); 
     return new CodingBlastDbContext(builder.Options); 
    } 
} 

然后,浏览到您的数据库项目并运行以下命令行:

DOTNET EF migration增加InitialMigration -s ../Web/

dotnet ef数据库更新-s ../Web/

-s代表启动项目和../Web/是我的网站/启动项目的位置。

resource

+2

我得到:没有找到配置文件'appsettings.json'并且不是可选的。物理路径是'C:\ Users \ XXX \ Documents \ Visual Studio 2017 \ Projects \ XXX \ src \ XXX.Api \ bin \ Debug \ netcoreapp2.0 \ appsettings.json'。 我的appsettings位于C:\ Users \ XXX \ Documents \ Visual Studio 2017 \ Projects \ XXX \ src \ XXX.Api中。 – Reft

+0

确保你已将appsettings.json文件设置为复制本地应该修复它没有被发现的问题 – DaImTo

3

请验证您是否有参考

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" /> 
+3

我正在使用包含该引用的'。我也尝试了包括上述内容,但没有改变。 – badabing

2

您可以从this discussion尝试此解决方案,这是灵感by this post

public static IWebHost MigrateDatabase(this IWebHost webHost) 
{ 
    using (var scope = webHost.Services.CreateScope()) 
    { 
     var services = scope.ServiceProvider; 

     try 
     { 
      var db = services.GetRequiredService<MyContext>(); 
      db.Database.Migrate(); 
     } 
     catch (Exception ex) 
     { 
      var logger = services.GetRequiredService<ILogger<Program>>(); 
      logger.LogError(ex, "An error occurred while migrating the database."); 
     } 
    } 

    return webHost; 
} 
public static void Main(string[] args) 
{ 
    BuildWebHost(args) 
     .MigrateDatabase() 
     .Run(); 
} 
+1

我仍然收到:添加'IDesignTimeDbContextFactory '的实现...... – Reft

1

以前,您在Startup.cs的配置方法中配置了种子数据。现在建议您仅使用Configure方法来设置请求管道。应用程序启动代码属于Main方法。

重构的Main方法。使用Microsoft.Extensions.DependencyInjection

;:添加以下引用到的Program.cs使用MyProject.MyDbContextFolder

;

public static void Main(string[] args) 
 
{ 
 
    var host = BuildWebHost(args); 
 

 
    using (var scope = host.Services.CreateScope()) 
 
    { 
 
     var services = scope.ServiceProvider; 
 
     try 
 
     { 
 
      var context = services.GetRequiredService<MyDbConext>(); 
 
      DbInitializer.Initialize(context); 
 
     } 
 
     catch (Exception ex) 
 
     { 
 
      var logger = services.GetRequiredService<ILogger<Program>>(); 
 
      logger.LogError(ex, "An error occurred while seeding the database."); 
 
     } 
 
    } 
 

 
    host.Run(); 
 
}

1

在AppContext.cs除了AppContext类添加另一个类:

// required when local database deleted 
public class ToDoContextFactory : IDesignTimeDbContextFactory<AppContext> 
{ 
    public AppContext CreateDbContext(string[] args) 
    { 
     var builder = new DbContextOptionsBuilder<AppContext>(); 
      builder.UseSqlServer("Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true"); 
     return new AppContext(builder.Options); 
    } 
} 

这将解决你的第二个问题:

"Unable to create an object of type 'MyContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project,

之后,你会能够添加迁移初始化al并通过运行update-database命令执行它。 但是如果运行这些命令时没有数据库尚未在本地SqlServer中你会得到像你的第一个错误的警告:“错误

occurred while calling method 'BuildWebHost' on class 'Program'... The login failed. Login failed for user '...'"

但它不是错误,因为迁移将被创建,它可以是 所以只是第一次忽略这个错误,而后者因为Db会存在,所以不会再发生。

2

东西真的帮了我为这篇文章:https://elanderson.net/2017/09/unable-to-create-an-object-of-type-applicationdbcontext-add-an-implementation-of-idesigntimedbcontextfactory/

的基本思路是,在超过从.NET核心1到2的变化都DB初始化应该被移出StartUp.cs和Program.cs中。否则,在执行任务时,EF任务会尝试并运行您的数据库。 “

”在官方迁移文档(https://docs.microsoft.com/en-us/ef/core/miscellaneous/1x-2x-upgrade)中有一段很漂亮的标题为“移动数据库初始化代码”,我似乎已经错过了,所以在你像任何一个兔子洞一样降下来之前,确保这不是什么导致您需要添加IdesignTimeDbContextFactory的实现。“

+0

谢谢,这也帮助了我。 – Sergey

0

更好的解决方案:

如果你的启动项目是一个ASP.NET Core应用程序,工具试图获得来自应用程序的服务提供商DbContext对象。

该工具首先尝试通过调用Program.BuildWebHost()并访问IWebHost.Services属性来获取服务提供者。

Program.cs中

public static IWebHost BuildWebHost(string[] args) => 
    WebHost.CreateDefaultBuilder(args) 
     .UseStartup<Startup>() 
     .Build(); 
0

后主要方法添加此方法在我来说,我得到了这个问题,因为我有一个名为SeedData.EnsurePopulated()方法被称为我的Startup.cs文件。

public class Startup 
{ 
    public Startup(IConfiguration configuration) => Configuration = configuration; 
    public IConfiguration Configuration { get; } 

    public void ConfigureServices(IServiceCollection services) 
    { 
     // 
    } 

    public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
    { 
     app.UseDeveloperExceptionPage(); 
     app.UseStatusCodePages(); 
     app.UseStaticFiles(); 
     app.UseSession(); 
     app.UseMvc(routes => 
     { 
      // 
     }); 

     SeedData.EnsurePopulated(app); 
    } 
} 

SeedData类的工作是将初始数据添加到数据库表。它的代码是:

public static void EnsurePopulated(IApplicationBuilder app) 
    { 
     ApplicationDbContext context = app.ApplicationServices.GetRequiredService<ApplicationDbContext>(); 
     context.Database.Migrate(); 
     if (!context.Products.Any()) 
     { 
      context.Products.AddRange(
      new Product 
      { 
       Name = "Kayak", 
       Description = "A boat for one person", 
       Category = "Watersports", 
       Price = 275 
      }, 
      .... 
      ); 
      context.SaveChanges(); 
     } 
    } 

SOLUTION

做迁移只是注释掉SeedData类的调用在Startup.cs文件前。

// SeedData.EnsurePopulated(app); 

这解决了我的问题,并希望你的问题也以同样的方式解决。

相关问题