【问题标题】:EF 6.4 Migration with .NET Core and ef6.dll yields in NullReferenceException使用 .NET Core 和 ef6.dll 进行 EF 6.4 迁移会产生 NullReferenceException
【发布时间】:2020-04-03 13:11:04
【问题描述】:

我正在创建一个迁移包,供我们的数据库团队外部使用,以执行实体框架迁移。该捆绑包由实体框架项目(包括我们所有的迁移)和来自实体框架 6.4 NuGet 包的ef6.dll 迁移工具组成,该工具位于ef64package/tools/netcoreapp3.0/any。

迁移包还包含一个简单的 PowerShell 脚本,它以某种方式执行 ef6.dll,如下所示:

dotnet .\ef6.dll database update --verbose --assembly MyApp.Core.EF.dll --connection-string "Data Source=localhost;Initial Catalog=MyApp;Trusted_Connection=True;" --connection-provider "System.Data.SqlClient"

使用 migrate.exe(在早期版本的 Entity Framework 中)和用于 .NET Framework 的 ef6.exe 这个捆绑包工作得很好。但是在切换到.NET Core和ef6.dll之后执行会出现如下错误:

Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Data.Entity.Internal.LazyInternalConnection.CreateConnectionFromProviderName(String providerInvariantName)
   at System.Data.Entity.Internal.LazyInternalConnection.InitializeFromConnectionStringSetting(ConnectionStringSettings appConfigConnection)
   at System.Data.Entity.Internal.LazyInternalConnection.Initialize()
   at System.Data.Entity.Internal.LazyInternalConnection.get_Connection()
   at System.Data.Entity.Internal.LazyInternalContext.get_Connection()
   at System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config, DbConnectionInfo connectionInfo, Func`1 resolver)
   at System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbConnectionInfo connectionInfo)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState, Boolean calledByCreateDatabase)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
   at System.Data.Entity.Infrastructure.Design.Executor.CreateMigrator(DbMigrationsConfiguration configuration)
   at System.Data.Entity.Infrastructure.Design.Executor.UpdateInternal(String targetMigration, Boolean force, DbConnectionInfo connectionInfo, String migrationsConfigurationName)
   at System.Data.Entity.Infrastructure.Design.Executor.Update.<>c__DisplayClass0_0.<.ctor>b__0()
   at System.Data.Entity.Infrastructure.Design.Executor.OperationBase.Execute(Action action)
Object reference not set to an instance of an object.

一个非常一般的错误,但根据 EF 源代码 (https://github.com/dotnet/ef6/blob/02104044fae2aca5d3a1f50f55f4af940a3c64a8/src/EntityFramework/Internal/LazyInternalConnection.cs),我看起来好像缺少 DbProviderFactory 注册或 providerInvariantName 在此过程中搞砸了。我有一种感觉,这是由于缺少配置或依赖关系造成的副作用。但到目前为止我无法弄清楚如何解决这个错误。

关于如何修复此错误的任何想法? 其他创建独立迁移包的方法也非常受欢迎。

提前致谢!

【问题讨论】:

    标签: entity-framework .net-core


    【解决方案1】:

    这就是我让它工作的方式:

    dotnet exec --depsfile MyApp.Core.EF.json --runtimeconfig MyApp.Core.EF.runtimeconfig.json "....\packages\entityframework\6.4.0\tools\netcoreapp3.0\any\ef6.dll" database update --assembly MyApp.Core.EF.dll --connection-string "xxx" --verbose
    

    另请参阅Github issue 或 Entity Framework Migration Azure DevOps Release Pipeline。

    【讨论】:

      【解决方案2】:

      Entity Framework (6.4.4) + Net Core 3.x 的迁移需要一个可执行应用程序作为入口点。 (“旧”迁移仅适用于包含数据库上下文的 dll。)
      您只需要添加一个可执行应用程序(或创建一个虚拟命令行应用程序),并在命令中指定它。 这是不明显的,因为所有示例都假设您只有一个带有单个 dll 的项目,并且不会对此发出警告。

      如果您检查 ef6.dll 的语法,您会发现主应用程序 dll... 的参数不存在。
      但是,它可以通过使用未记录的dotnet exec 语法来解决。

      dotnet exec --depsfile Your.App.Project.deps.json --runtimeconfig Your.App.Project.runtimeconfig.json .\ef6.dll" database update --verbose --assembly Your.Database.Project.dll --connection-string "&lt;standard sql string&gt;"

      请注意 .deps 文件和 .runtimeconfig 来自您的可执行应用程序,并且该应用程序的所有 .dll 文件都必须存在于文件夹中(工具会检查)。其余参数是 ef6.dll 的标准参数 - 包含数据库上下文、连接字符串、可选提供程序类型的 .dll 文件的名称。

      一些注意事项:

      • 确保“/runtimes”文件夹(如果存在)与应用程序 dll 文件一起复制。缺少它会给出一个关于缺少文件夹中已经存在的 .dll 的模糊错误,但显然 Microsoft.Data.SqlClient.dll 需要在运行时文件夹中添加一些秘密子 dll。
      • .net Core 不再有 packages 文件夹,因此您必须弄清楚它们在给定计算机上的位置,或者将 ef6.dll 复制到您的源中。
      • 在本地测试时,请确保取消转义连接字符串中的双斜杠。当您使用 Server=.\\SQLEXPRESS 而不是 Server=.\SQLEXPRESS 时,出现另一个晦涩的错误并不好玩

      这篇文章的作者现在正式讨厌 ef6.dll。

      【讨论】:

        猜你喜欢
        • 2021-12-29
        • 2018-08-15
        • 2019-03-20
        • 2018-11-30
        • 2017-05-27
        • 1970-01-01
        • 1970-01-01
        • 2020-10-02
        • 2021-09-29
        相关资源
        最近更新 更多