升级到ASP.NET Core 2.0后无法创建迁移

ruh*_*uhm 86 c# entity-framework-core asp.net-core-mvc asp.net-core asp.net-core-2.0

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

我越来越

"在类'Program'上调用方法'BuildWebHost'时发生错误.继续没有应用服务提供者.错误:发生了一个或多个错误.(无法打开登录请求的数据库"...".登录失败.登录用户'...'失败

"无法创建'MyContext'类型的对象.将'IDesignTimeDbContextFactory'的实现添加到项目中,或者参见 https://go.microsoft.com/fwlink/?linkid=851728以获取在设计时支持的其他模式."

我之前运行的命令是$ 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();
}
Run Code Online (Sandbox Code Playgroud)

小智 98

您可以在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,导航到您的数据库项目并从命令行运行以下命令:

dotnet ef migrations add InitialMigration -s ../Web/

dotnet ef database update -s ../Web/

-s stands for startup project and ../Web/ is the location of my web/startup project.
Run Code Online (Sandbox Code Playgroud)

资源

  • 我收到:找不到配置文件'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. (2认同)

tch*_*dze 56

没必要IDesignTimeDbContextFactory.

add-migration initial -verbose

这将揭示下的细节

在"Program"类上访问IWebHost时发生错误.继续没有应用程序服务提供商.

警告,这是问题的根本原因.

在我的情况下,问题是,拥有ApplicationRole : IdentityRole<int>和调用services.AddIdentity<ApplicationUser, IdentityRole>()导致下面的错误

System.ArgumentException: GenericArguments[1], 'Microsoft.AspNetCore.Identity.IdentityRole', 
on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,
TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type 'TRole'.
---> System.TypeLoadException: GenericArguments[1], 'Microsoft.AspNetCore.Identity.IdentityRole', 
on 'Microsoft.AspNetCore.Identity.UserStoreBase`8[TUser,TRole,TKey,TUserClaim,
TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type parameter 'TRole'.
Run Code Online (Sandbox Code Playgroud)

  • @tchelidze谢谢您,在我的情况下,我的ApplicationDbContext中没有无参数的构造函数。 (4认同)
  • 是的--Verbose有助于实际发现真正的问题.在我的情况下,没有添加AddDbContext服务启动. (3认同)
  • dotnet ef迁移添加InitialCreate --verbose (2认同)

小智 14

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

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
    }
}
Run Code Online (Sandbox Code Playgroud)

只需重命名BuildWebHost()CreateWebHostBuilder(),因为迁移默认情况下使用此方法。

  • 什么。这应该在处理这个问题的每个页面上做广告_你是认真的_。即时成功。谢谢你。 (4认同)

Ali*_*yat 11

更好的解决方案:

解决方案1:

将Web应用程序项目设置为“设置为启动项目”

在Visual Studio中从菜单Tools-> NuGet Package Manger-> Package Manager Console中打开Package Manager控制台,以执行以下命令。

Add-Migration Init -Verbose
Run Code Online (Sandbox Code Playgroud)

注意:使用该–verbose选项可以查看应用于目标数据库的SQL语句。它包含详细的错误。

解决方案2:

如果您的启动项目是一个ASP.NET Core应用程序,则这些工具会尝试DbContext从应用程序的服务提供商获取对象。

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

在以下Main方法中添加此方法Program.cs

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build();
Run Code Online (Sandbox Code Playgroud)

更新.NET Core 2.2

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
} 
Run Code Online (Sandbox Code Playgroud)

更新.NET Core 3.0

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}
Run Code Online (Sandbox Code Playgroud)

不要更改方法的名称或签名CreateHostBuilder。在Entity Framework Core tools希望找到一个CreateHostBuilder 用于配置主机而不运行的应用程序的方法。

解决方案3

确保已添加Dbcontext到依赖项注入: AddDbContext<TContext>将使您的DbContext类型TContextDbContextOptions<TContext>可以从服务容器中进行注入。这需要向您的DbContext类型添加一个构造函数参数accepts DbContextOptions<TContext>

示例:在Startup.cs中

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<AppDbContext>(options => options.UseSqlServer(connectionString));
}
Run Code Online (Sandbox Code Playgroud)

AppDbContext代码:

public class AppDbContext: DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
      :base(options)
    { }

}
Run Code Online (Sandbox Code Playgroud)

  • 感谢“ -Verbose”标志。它帮助我找到了异常的根本原因。 (3认同)
  • 伙计们,如果您使用的是 ASP.NET Core 2.1+,则 BuildWebHost 方法将具有不同的名称 - CreateWebHostBuilder 因为 https://docs.microsoft.com/en-us/aspnet/core/migration/20_21?view=aspnetcore- 2.1#changes-to-main 将 CreateWebHostBuilder 重命名为 BuildWebHost,迁移将找到 BuildWebHost 并从中获取 DbContext。 (2认同)
  • 谢谢队友,花了2个小时解决了配置问题,无需使用`IDesignTimeDbContextFactory` (2认同)

小智 11

就我而言,问题的原因是多个启动项目。我的解决方案中有三个项目:Mvc,Api和Dal。Dal项目中的DbContext和迁移。

我已经配置了多个启动项目。当我单击开始时,Mvc和Api项目都在运行。但是在这种情况下,我遇到了这个错误。

“无法创建类型为'MyContext'的对象。将'IDesignTimeDbContextFactory'的实现添加到项目中,或者在设计时参见 https://go.microsoft.com/fwlink/?linkid=851728&clcid=0x804

在将Mvc设置为唯一的启动项目并在Package Manager控制台中选择Dal之后,我可以成功添加迁移。


bor*_*sdj 7

在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

“无法创建类型为'MyContext'的对象。将'IDesignTimeDbContextFactory'的实现添加到项目中,

之后,您将能够添加迁移初始值并通过运行update-database命令执行它。但是,如果在本地SqlServer中还没有数据库的情况下运行这些命令,则会收到类似第一个错误的警告:“一个错误

在类“程序”上调用方法“ BuildWebHost”时发生错误...登录失败。用户“ ...”的登录失败

但这不是错误,因为将创建迁移并可以执行迁移。因此,只需首次忽略此错误,由于Db将存在,因此不会再发生。