没有为此DbContext配置数据库上下文提供程序...尽管它有

时间:2017-06-04 11:00:44

标签: c# entity-framework-core npgsql

拥有3个程序集的解决方案:数据,域和Web。数据保存上下文,Web是.NET Core WebAPI应用程序,它们都在同一个解决方案目录中。我也使用Postgre作为数据库。

以下是ConfigureServices中的Startup.cs方法:

public void ConfigureServices(IServiceCollection services)
{
    string connectionString = Configuration.GetConnectionString("DefaultConnection");
            ...
    services.AddDbContext<WebStoreContext>(
        options => options.UseNpgsql(
            connectionString,
            (providerOptions) =>
            {
                providerOptions.CommandTimeout(20);
                providerOptions.MigrationsAssembly("WebStore.Data");
            }));

    services.AddMvc();
            ...
}

注意如何使用AddDbContext并传递optionsAction参数来配置数据库提供程序。

现在我使用命令行ef工具为db创建了初始迁移。 我已经进入了WebStore.Data并运行了:

dotnet ef --startup-project ..\WebStore.Web migrations add IntializeDb

这一切都很好。

当我尝试从同一目录运行时,问题就开始了:

dotnet ef database update
  

在'WebStoreContext'上找不到无参数构造函数。要么将无参数构造函数添加到'WebStoreContext',要么在与'WebStoreContext'相同的程序集中添加'IDbContextFactory'的实现。

我在DbContext派生类中声明无参数构造函数之前得到的上述错误,以及我声明一个后面的错误:

  

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

所以在我看来,尽管我提供了一个DbContextOptions实例,但无意义的构造函数仍然被调用。

然后我尝试了这个:

//parameterless constructor calling the one accepting the DbContextOptions argument
public WebStoreContext() : this(new DbContextOptionsBuilder<WebStoreContext>()
.UseNpgsql("UserID=****;Password=****;Host=localhost;Port=****;Database=webstore;Pooling=true;")
.Options){ }

得到了这个:

  

System.Reflection.TargetInvocationException:调用目标抛出了异常。 ---&GT; System.IO.FileLoadException:无法加载文件或程序集'System.Diagnostics.DiagnosticSource,Version = 4.0.1.1,Culture = neutral,PublicKeyToken = cc7b13ffcd2ddd51'。定位的程序集的清单定义与程序集引用不匹配。 (HRESULT异常:0x80131040)

还在试图弄清楚这里发生了什么。非常感谢帮助。

修改 我应用了Shay Rojansky的解决方案并且它有效,尽管我有以下问题:

  

System.IO.FileLoadException:无法加载文件或程序集   'System.Diagnostics.DiagnosticSource,Version = 4.0.1.1,   Culture = neutral,PublicKeyToken = cc7b13ffcd2ddd51'。位于   程序集的清单定义与程序集引用不匹配。   (来自HRESULT的异常:0x80131040)文件名:   'System.Diagnostics.DiagnosticSource,Version = 4.0.1.1,   Culture = neutral,PublicKeyToken = cc7b13ffcd2ddd51'at   Microsoft.EntityFrameworkCore.Infrastructure.RelationalServiceCollectionExtensions.AddRelational(IServiceCollection   服务)   Microsoft.Extensions.DependencyInjection.NpgsqlEntityFrameworkServicesBuilderExtensions.AddEntityFrameworkNpgsql(IServiceCollection   服务)   Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache&LT;&GT; c__DisplayClass4_1.b__2(Int64类型   k)at   System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKEY的   key,Func`2 valueFactory)at   Microsoft.EntityFrameworkCore.DbContext.InitializeServices()at   Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()   在   Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService [TService](IInfrastructure`1   访问者)   Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1   工厂)   Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(字符串   contextType)at   Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(字符串   targetMigration,String contextType)at   Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase&LT;&GT; c__DisplayClass0_1&LT; .ctor&GT; b__0()   在   Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(动作   行动)

     

无法加载文件或程序集   'System.Diagnostics.DiagnosticSource,Version = 4.0.1.1,   Culture = neutral,PublicKeyToken = cc7b13ffcd2ddd51'。位于   程序集的清单定义与程序集引用不匹配。   (HRESULT异常:0x80131040)

解决方案将其添加到.csproj文件中:

<PropertyGroup>
        <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
</PropertyGroup>

这显然是由于bug

3 个答案:

答案 0 :(得分:1)

根据EF Core getting started docs的建议,尝试在您的上下文中添加OnConfiguring方法:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
    optionsBuilder.UseNpgsql("...");
}

答案 1 :(得分:1)

我发现最简单的解决方法是从上下文中删除默认构造函数。只需要一个带有DBContentOptions或DBContentOptions的构造函数&lt;&gt;作为参数,然后传递给基类。

public class ApplicationDbContext : DbContext>
{
    #region Constructor
    public ApplicationDbContext(DbContextOptions options) : base(options) { }
    #endregion
}

但同意这并不理想。 Esp,如果您需要使用EF unity IOC之外的上下文。

希望这会帮助其他人。

答案 2 :(得分:0)

我遇到过这个问题,在运行任何命令时都不需要更改任何内容,只需添加--startup-project参数即可。 恩。
    dotnet ef数据库更新--startup-project .. \ WebStore.Web