EFCore无法识别数据库提供程序

时间:2017-05-27 20:35:08

标签: c# asp.net-core entity-framework-core ef-migrations

我有一个.Net Core WebApplication项目,其中Context类位于类库中。如果我在OnConfiguring(DbContextOptionsBuilder optionsBuilder)方法中对连接字符串进行硬编码,我可以生成迁移。由于最好让依赖注入管理上下文,我想将它添加到Startup Class。但是,当我这样做时,我收到以下错误:

  

没有为此DbContext配置数据库提供程序。可以通过覆盖DbContext.OnConfiguring方法或在应用程序服务提供程序上使用AddDbContext来配置提供程序。如果使用AddDbContext,那么还要确保您的DbContext类型在其构造函数中接受DbContextOptions对象,并将其传递给DbContext的基础构造函数。

DbContext类:

public class CustomerManagerContext : IdentityDbContext<User, Role, long, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>
{
    public CustomerManagerContext() { }
    public CustomerManagerContext(DbContextOptions<CustomerManagerContext> options) : base(options)
    {
    }

    //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    //{
    //    base.OnConfiguring(optionsBuilder);
    //    optionsBuilder.UseSqlServer("SecretConnectionString");
    //}


    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<User>().ToTable("Users");
        builder.Entity<Role>().ToTable("Roles");
        builder.Entity<UserClaim>().ToTable("UserClaims");
        builder.Entity<UserRole>().ToTable("UserRoles");
        builder.Entity<UserLogin>().ToTable("UserLogins");
        builder.Entity<RoleClaim>().ToTable("RoleClaims");
        builder.Entity<UserToken>().ToTable("UserTokens");

    }
}

启动类 - 配置服务方法

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<CustomerManagerContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
    );

    services.AddEntityFrameworkSqlServer()
        .AddDbContext<CustomerManagerContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<User, Role>()
        .AddEntityFrameworkStores<CustomerManagerContext>()
        .AddDefaultTokenProviders();
}

2 个答案:

答案 0 :(得分:4)

这让我很难受,并得到如下错误:

  • No database provider has been configured for this DbContext.
  • No design-time services were found.
  • The server was not found or was not accessible.

但是最后我得到了一个非常简单的解决方案/解决方法:

  • 在解决方案(或命令行)中设置默认的启动项目
  • 在您的Startup.cs add the migration-project 中:

    public void ConfigureServices(IServiceCollection services)
    {
        var myDbContextAssemblyName = typeof(MyDbContext).Assembly.GetName().Name;
        var connectionString = Configuration.GetConnectionString(MyDbContext.ConnectionStringName);
        services.AddDbContext<MyDbContext>(options => options.UseSqlServer(
            connectionString,
            x => x.MigrationsAssembly(myDbContextAssemblyName)));
            // do more ...
        }
    
  • 在连接字符串中的
  • 使用 IP地址和端口号(受this corefx issue启发),而不是服务器名称/ dns(FWIW:{{ 3}})。 所以现在我在appsettings.Development.json中有这个了:

    “ ConnectionStrings”:{         “ MyConnectionStringName”:“数据源= 10.1.2.3,1433;初始目录= MyCatalog;集成安全性= SSPI”     }

TLDR:其他建议

我发现了很多其他建议,并且我还会提到一些看起来很有趣的建议。也许会帮助其他人:

命令行中的项目名称

在命令行中提及启动项目和迁移项目

Update-Database -Verbose -Project x.Data -StartupProject x.Web

从代码迁移

一个人也可以通过query to get IP致电迁移 ,“ 用于具有本地数据库的应用程序”。 (我想否则会在多个节点上运行,是否可能同时出现并发问题启动多个运行时迁移?)

myDbContext.Database.Migrate();

在Main.cs中设置DbContext

StartUp状态:

  

问题在于,当EF调用CreateWebHostBuilder或   BuildWebHost无需运行Main。 (这是故意的   因为EF需要建立模型并使用DbContext   启动应用程序。)这意味着当EF调用这些   方法,静态IConfiguration属性仍然为null,因为它   仅在Main中设置。因此,您需要确保   EF调用以下方法之一时,将设置/处理IConfiguration:   使用IDesignTimeDbContextFactory

这对我来说不是必需的,因为.Net Core 2 This EntityFrameworkCore issue

将IDesignTimeDbContextFactory与环境变量一起使用

loads the configuration behind the scenes状态:

  

执行此操作的典型方法是在IDesignTimeDbContextFactory中读取文件,环境变量或类似内容。

对我来说这似乎太过分了。

设计时的DbContext创建

This EntityFrameworkCore issue提到:

  

一些EF核心工具命令(例如,迁移   命令)要求在设计时创建派生的DbContext实例   时间以收集有关应用程序的实体类型的详细信息   以及它们如何映射到数据库模式。

他们提到了提供这种设计时DbContext的这些方法:

  • 来自应用程序服务:对于作为启动项目的ASP.NET Core应用程序:

      

    这些工具尝试从应用程序的DbContext对象中获取   服务提供者。 [...]工具首先尝试获得服务   提供商通过调用Program.BuildWebHost() [JP:或   CreateWebHostBuilder]并访问IWebHost.Services   属性。 DbContext本身及其任何依赖项   构造函数需要在应用程序的应用程序中注册为服务   服务提供者。这可以通过构造函数轻松实现   在DbContext上,该实例采用   DbContextOptions<TContext>作为参数,并使用   AddDbContext<TContext>方法。

  • 使用无参数的构造函数

      

    如果无法从应用程序服务获得DbContext   提供程序,这些工具会在内部查找派生的DbContext类型   项目。然后,他们尝试使用带有以下内容的构造函数创建实例   没有参数。如果DbContext可以是默认构造函数   使用OnConfiguring方法进行配置。

  • 在设计时工厂

      

    您还可以通过以下方式告诉工具如何创​​建DbContext   实现IDesignTimeDbContextFactory<TContext>接口:如果   在同一个目录中找到实现此接口的类   项目作为派生的DbContext或在应用程序的启动中   项目,这些工具会绕过创建DbContext的其他方式   并使用设计时工厂。

答案 1 :(得分:0)

在将选项与dbcontext一起添加到dbcontext等服务时,我遇到了同样的问题:-

authorized_keys

然后我添加了不带以下选项的dbcontext,它为我解决了问题

services.AddDbContext<TodoContext>(options => 
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

我还必须向dbcontext类添加OnConfiguring方法,以便上下文可以访问连接字符串:-

services.AddDbContext<TodoContext>();

由于我只是从核心开始,所以我不确定这是否是正确的处理方式,但是here是一个答案,它更详细地解释了此问题