无法加载文件或程序集'Microsoft.Data.SqlClient

Could not load file or assembly 'Microsoft.Data.SqlClient

我正在从框架 4.7.2 测试项目中成功调用 .net 标准 2.0 库。

如果我使用我的 .net 标准 2.0 dll (SBD.Standard) 并创建一个引用它的新 winforms 项目然后我被要求添加

Microsoft.EntityFrameworkCore, 
then Microsoft.EntityFrameworkCore.SqlServer, 
then Microsoft.Data.SqlClient 

然后我的项目运行成功。 (虽然如果自动添加额外的包会更理想)

但是,如果我尝试通过使用 Azure DevOps 构建的 Nuget 包分发我的库,就会出现问题。

然而,当我通过 Nuget 分发标准库(使用 Azure DevOps 创建 Nuget)并将其包含在新项目中时,我遇到了错误。

调用堆栈为

System.IO.FileNotFoundException : Could not load file or assembly 'Microsoft.Data.SqlClient, Version=1.0.19269.1, Culture=neutral, PublicKeyToken=23ec7fc2d6eaa4a5' or one of its dependencies. The system cannot find the file specified.
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerConnection.CreateDbConnection()
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.get_DbConnection()
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.CreateCommand(RelationalCommandParameterObject parameterObject, Guid commandId, DbCommandMethod commandMethod)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at SBD.Standard.Helpers.HandyFuncs.QueueCommand(ApiDbContext connect, WorkTypeEnum workType, String 

导致问题的代码行是

public static int QueueCommand(ApiDbContext connect, WorkTypeEnum workType, string description, int jobId, int signature, XElement elem)
{
    var command =
        connect.EngineCommandQueues.SingleOrDefault(
            c =>
                (c.Status == 0|| c.Status == 2) &&
                c.Signature == signature);

我确实发现我需要安装以下软件包

Microsoft.EntityFrameworkCore 3.1.1
Microsoft.EntityFrameworkCore.SqlServer 3.1.1 which has a dependency on Microsoft.Data.SqlClient >=1.019269.1

我看到 Microsoft.Data.SQLClient v1.0.19269.1 已安装

我尝试安装 System.Linq

我在 Nuget 中看到 Microsoft.Data.SqlClient

的注释

When running on Windows, this library has a dependency on Microsoft.Data.SqlClient.SNI on .NET Framework

并安装了 Microsoft.Data.SqlClient.SNI v1.0.19235.1

我尝试将 Microsoft.Data.SqlClient 升级到 1.1,错误变为

System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.TdsParser' threw an exception. ---> System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNILoadHandle' threw an exception. ---> System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNINativeMethodWrapper' threw an exception. ---> System.ComponentModel.Win32Exception: Failed to load C:\Dev2\Combridge\SBD.ComBridge\UnitTestProjectStandard\bin\Debug\x86\SNI.dll ---> System.ComponentModel.Win32Exception: The specified module could not be found
    at Microsoft.Data.SqlClient.SNINativeMethodWrapper..cctor() in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\Interop\SNINativeMethodWrapper.cs:line 64
--- End of inner exception stack trace ---
    at Microsoft.Data.SqlClient.SNINativeMethodWrapper.SNIInitialize()
   at Microsoft.Data.SqlClient.SNILoadHandle..ctor() in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\TdsParserSafeHandles.cs:line 36
   at Microsoft.Data.SqlClient.SNILoadHandle..cctor() in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\TdsParserSafeHandles.cs:line 17
--- End of inner exception stack trace ---
    at Microsoft.Data.SqlClient.TdsParser..cctor() in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\TdsParser.cs:line 166
--- End of inner exception stack trace ---
    at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionPool.cs:line 1411
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionPool.cs:line 1310
   at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection) in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionFactory.cs:line 357
   at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionInternal.cs:line 773
   at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionClosed.cs:line 72
   at Microsoft.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry) in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlConnection.cs:line 1860
   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry) in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlConnection.cs:line 1853
   at Microsoft.Data.SqlClient.SqlConnection.Open() in E:\agent1\_work\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlConnection.cs:line 1421
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at lambda_method(Closure , QueryContext )
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)

[更新] 阅读 This GitHub post 看来它可能与 Azure Devops

有关

post提到

Win32Exception: Failed to load C:__source_code\repo1\Simplified\bin\x86\SNI.dll So it's trying to load the 32 bit version of sni.dll and it isn't present.

That makes me suspect that you build it on a 64 bit system and then just transferred the files to the other machine. You need to publish the project for an x86 target to get the right native dependency resolved. Give it a try.

我是 运行 Windows 10 所以我不明白为什么它会尝试加载 sni.dll

的 32 位版本

我可以在 Azure Artifiacts 中看到

Microsoft.Data.SqlClient.SNI 1.0.19235.1

[更新]

我从 中了解到,我需要强制 MSBuild 创建/更新包含必要绑定重定向的 YourProject.dll.config 文件。 所以 Nuget 也应该创建该配置文件。我想知道这对事情有何影响。

我的天蓝色-pipelines.yml是

# .NET Desktop
# Build and run tests for .NET Desktop or Windows classic desktop solutions.
# Add steps that publish symbols, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net

trigger:
- master

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
  Major: '2'
  Minor: '0'
  Patch: '0'

steps:
- task: NuGetToolInstaller@0
  inputs:
    versionSpec: '>=4.3.0'
    checkLatest: true

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

- task: NuGetCommand@2
  inputs:
    command: pack
    packagesToPack: '**/*.csproj'
    versioningScheme: byPrereleaseNumber
    majorVersion: '$(Major)'
    minorVersion: '$(Minor)'
    patchVersion: '$(Patch)'

- task: NuGetCommand@2
  inputs:
    command: pack
    packagesToPack: '**/*.vbproj'
    versioningScheme: byPrereleaseNumber
    majorVersion: '$(Major)'
    minorVersion: '$(Minor)'
    patchVersion: '$(Patch)'

- task: NuGetCommand@2
  displayName: 'NuGet push'
  inputs:
    command: push
    publishVstsFeed: 'SBDCommonFeed'
    allowPackageConflicts: true

[更新]

我尝试更改 yaml 以使用 dotnet pack 但出现错误

[更新]

我尝试用

替换 yaml 的 pack 部分
- task: DotNetCoreCLI@2
  inputs:
    command: 'pack'
    selectOrConfig: 'config'
    nugetConfigPath: '$(System.DefaultWorkingDirectory)/NuGet.config'
    externalEndpoints: $(externalFeedCredential)

现在我得到资源授权问题

当我单击授权按钮时,我收到一条消息:权限不足或缺少资源。即使我以存储库所有者的身份登录。

我想我需要学习在 externalEndpoints 中放入什么

[更新]

我试过这个

- task: DotNetCoreCLI@2
  inputs: 
    command: 'pack'
    outputDir: '$(Build.ArtifactStagingDirectory)/TestDir'

现在错误变成了

 error MSB4057: The target "pack" does not exist in the project.

正在调查

Although it would be ideal if the extra packages were added automatically.

假设我们有一个 .net standard 项目依赖于 Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore.SqlServer 和其他包。我们的预期行为是创建一个 nuget 包,其中 xx.nuspec 文件包含关于 dependencies.

的定义

但是关于nuget pack命令有one issue,它不能很好地用于.net core/standard项目。 nuget packdotnet pack都可以成功创建.net standard个nuget包,但是pack successfully并不代表好的包。

由于上述问题,nuget pack 创建的包将丢失 Package.nuspec 文件中的一些依赖项。 (将xx.nupkg重命名为xx.zip,然后我们可以查看包内的内容,我们会看到xx.nuspec文件)

以上步骤可能会导致 missing assembly 等运行时错误。因此,为了使额外的包自动添加并避免丢失引用变得理想,我们建议对使用 PackageReference 格式的项目使用 dotnet pack 命令。 (无论是本地的 dotnet pack 命令还是 Azure Devops Piepilne 中的 dotnet pack 任务)

只是在引用 netstandard 2.0 项目 (ef core 3.x) 的 ASP.NET 4.7.2(从 net 4.6 更新)项目中遇到了同样的错误。 (在 Azure 应用服务上)

在尝试 clean/rebuild/nuget 重新安装后.. 我从应用程序服务中删除了所有内容并再次发布了项目。错误已消除。