gpt4 book ai didi

c# - EFCore 不识别数据库提供程序

转载 作者:行者123 更新时间:2023-11-30 15:18:18 25 4
gpt4 key购买 nike

我有一个 .Net Core WebApplication 项目,其中上下文类位于类库中。如果我在 OnConfiguring(DbContextOptionsBuilder optionsBuilder) 方法中硬编码连接字符串,我可以生成迁移。因为让依赖注入(inject)管理上下文更好,所以我想将它添加到启动类中。但是,当我这样做时,出现以下错误:

No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for 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");

}
}

启动类 - ConfigureServices 方法

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

最佳答案

这让我很难受,出现如下错误:

  • 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:query to get IP) .所以现在我的 appsettings.Development.json 里有了这个:

    “连接字符串”:{“MyConnectionStringName”:“数据源=10.1.2.3,1433;初始目录=MyCatalog;集成安全性=SSPI”

TLDR:其他建议

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

命令行中的项目名称

在命令行中提及 startup-project 和 migration-project:

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

补充(来自评论):这也适用于 dotnet CLI:

dotnet ef migrations add <MIGRATION_NAME> --project <DATABASE_PROJECT_DIR> --startup-project <STARTUP_PROJECT_DIR> dotnet ef database update --project <DATABASE_PROJECT_DIR> --startup-project <STARTUP_PROJECT_DIR> 

从代码迁移

也可以在 StartUp 调用迁移, "用于具有本地数据库的应用"。 (我想否则在多个节点上运行,可能会同时启动多个运行时迁移并发问题?)

myDbContext.Database.Migrate();

在Main.cs中设置DbContext

This EntityFrameworkCore issue状态:

The problem is that when EF calls either CreateWebHostBuilder orBuildWebHost it does so without running Main. (This is intentionalbecause EF needs to build the model and use the DbContext withoutstarting the application.) This means that when EF invokes on of thesemethods the static IConfiguration property is still null--since itis only set in Main. So, you'll need to either make sure thatIConfiguration is set/handled when EF calls one of these methods, oruse IDesignTimeDbContextFactory.

这对我来说不是必需的,我猜是因为 .Net Core 2 loads the configuration behind the scenes .

通过环境变量使用 IDesignTimeDbContextFactory

This EntityFrameworkCore issue状态:

The typical way to do this is to read a file, an environment variable, or similar inside IDesignTimeDbContextFactory.

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

在设计时创建 DbContext

Microsoft documentation提及:

Some of the EF Core Tools commands (for example, the Migrationscommands) require a derived DbContext instance to be created at designtime in order to gather details about the application's entity typesand how they map to a database schema.

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

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

The tools try to obtain the DbContext object from the application'sservice provider. [...] The tools first try to obtain the serviceprovider by invoking Program.BuildWebHost() [JP: orCreateWebHostBuilder] and accessing the IWebHost.Servicesproperty. The DbContext itself and any dependencies in itsconstructor need to be registered as services in the application'sservice provider. This can be easily achieved by having a constructoron the DbContext that takes an instance ofDbContextOptions<TContext> as an argument and using theAddDbContext<TContext> method.

  • 使用不带参数的构造函数

If the DbContext can't be obtained from the application serviceprovider, the tools look for the derived DbContext type inside theproject. Then they try to create an instance using a constructor withno parameters. This can be the default constructor if the DbContextis configured using the OnConfiguring method.

  • 来自设计时工厂

You can also tell the tools how to create your DbContext byimplementing the IDesignTimeDbContextFactory<TContext> interface: Ifa class implementing this interface is found in either the sameproject as the derived DbContext or in the application's startupproject, the tools bypass the other ways of creating the DbContextand use the design-time factory.

关于c# - EFCore 不识别数据库提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44221389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com