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

6
我成功地从一个框架 4.7.2 的测试项目中调用了一个 .net standard 2.0 库。 references 如果我使用我的 .net standard 2.0 dll (SBD.Standard) 创建一个新的 WinForms 项目并引用它,那么我会被要求添加。
Microsoft.EntityFrameworkCore, 
then Microsoft.EntityFrameworkCore.SqlServer, 
then Microsoft.Data.SqlClient 

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

enter image description here

然而,如果我尝试使用 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的注意事项

在Windows上运行时,该库依赖于.NET Framework上的Microsoft.Data.SqlClient.SNI

并且已安装了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\31\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\31\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\TdsParserSafeHandles.cs:line 36
   at Microsoft.Data.SqlClient.SNILoadHandle..cctor() in E:\agent1\_work\31\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\31\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\31\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\31\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\31\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\31\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\31\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\31\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\31\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlConnection.cs:line 1853
   at Microsoft.Data.SqlClient.SqlConnection.Open() in E:\agent1\_work\31\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)

【更新】阅读此GitHub帖子,似乎与Azure Devops有关。
该帖子提到:

Win32Exception:无法加载C:__source_code\repo1\Simplified\bin\x86\SNI.dll,因此它试图加载sni.dll的32位版本,但不存在。

这让我怀疑您是在64位系统上构建的,然后将文件转移到另一台计算机。 您需要发布x86目标的项目以获取正确的本地依赖项解析。 试试看。

我正在运行Windows 10,所以我不明白为什么它要尝试加载SNI.dll的32位版本。
我可以在Azure Artifacts中看到:

Microsoft.Data.SqlClient.SNI 1.0.19235.1

【更新】
我看到从this question中,需要强制MSBuild创建/更新YourProject.dll.config文件,其中包含必要的绑定重定向。因此,Nuget也应该创建该配置文件。我想知道这会影响什么。

我的azure-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://learn.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,但出现错误。

error

[更新]

我尝试将yaml文件中的pack部分替换为

- task: DotNetCoreCLI@2
  inputs:
    command: 'pack'
    selectOrConfig: 'config'
    nugetConfigPath: '$(System.DefaultWorkingDirectory)/NuGet.config'
    externalEndpoints: $(externalFeedCredential)

现在我遇到resource authorization issue 资源授权问题

当我点击授权按钮时,会收到一条消息:权限不足或缺少资源。即使我已经登录为存储库所有者。

我猜我需要学习在externalEndpoints中放置什么。

[更新]

我尝试了这个方法

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

现在错误变成了。
 error MSB4057: The target "pack" does not exist in the project.

正在调查 此答案


https://github.com/dotnet/runtime/issues/26543 - Kirsten
我将尝试将 System.Data.SqlClient 添加到我的标准库中。 - Kirsten
我遇到了这个问题。不知道它是否与 https://dev59.com/v1cP5IYBdhLWcg3wr7_j 有关。 - Kirsten
1
当您在VS本地开发库项目时,是否引用了上述三个包?如果我们在VS中创建nuget(右键单击项目=>打包),并在另一个项目中使用它,是否一切正常?错误消息有点奇怪,但既然您“然后我的项目成功运行”,我认为您的Azure devops中的“打包步骤”应该有问题...您使用dotnet pack命令吗? - LoLance
不是Nuget相关任务,请使用dotnet相关任务。请参见此处。如果您正在处理.net core/.net standard项目,则建议使用此任务。请参见Nuget任务中的注意事项 - LoLance
显示剩余6条评论
4个回答

3

虽然自动添加额外的软件包会是理想的。

假设我们有一个依赖于 Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore.SqlServer 和其他软件包的 .net standard 项目。我们期望的行为是在创建 nuget 包时,在其 xx.nuspec 文件中定义 依赖关系

但是,关于 nuget pack 命令,存在 一个问题,它不能很好地处理 .net core/standard 项目。无论是 nuget pack 还是 dotnet pack 都可以成功创建 .net standard nuget 包,但是“成功打包”并不意味着包是好的。

由于上述问题的影响,由nuget pack创建的包将在Package.nuspec文件中失去一些依赖项。(将xx.nupkg重命名为xx.zip,然后我们可以检查包内的内容,我们会看到xx.nuspec文件)
上述步骤可能会导致运行时错误,如missing assembly。因此,为了使额外的包自动添加并避免缺失引用,我们建议对使用PackageReference格式的项目使用dotnet pack命令。(无论是本地的dotnet pack命令还是Azure Devops Piepilne中的dotnet pack任务)

我在尝试发布整个代码库时遇到了问题。我认为这是因为它包含框架和标准项目。我将提出一个新的问题。 - Kirsten
https://stackoverflow.com/questions/60181799/can-i-mix-framework-projects-and-net-standard-projects-in-the-same-repository - Kirsten
https://stackoverflow.com/questions/60197552/how-do-i-get-azure-devops-to-create-a-correct-nuspec-for-a-net-standard-2-0-pro - Kirsten

2

我通过更新测试项目的包引用解决了这个错误。

具体来说,我编辑了我的项目文件,包含以下行:

  <ItemGroup>
    ...
    <PackageReference Include="Microsoft.Data.SqlClient" Version="5.0.1" />
  </ItemGroup>

1

我刚刚在使用ASP.NET 4.7.2项目(从net 4.6升级而来),引用了netstandard 2.0项目(ef core 3.x)时遇到了相同的错误。(在Azure应用程序服务上)

尝试清理/重建/重新安装Nuget后,我将所有内容从应用程序服务中删除,并重新发布了项目。错误消失了。


1

如错误信息中所述,此问题是由应用程序期望的版本与您安装的版本之间的差异引起的。

要解决版本问题,在 Visual Studio 中,右键单击解决方案,选择“管理解决方案的 NuGet 包”选项,然后转到“更新”选项卡,搜索并选择出现问题的参考文献。然后将其升级/降级为错误中给出的版本。(您可能需要暂时禁用 NuGet 选项中的软件包源才能执行此操作。)要检查是否安装了正确的参考版本,请右键单击该参考文献,然后转到“属性”并检查版本。

如果版本仍未更新,则可能需要手动添加。要执行此操作,请在解决方案资源管理器中,右键单击“引用”,然后选择“添加引用”选项。然后选择“浏览”。您将被引导到文件资源管理器。从那里进入项目->src->软件包->参考名称->lib->.net 版本,并选择参考的 dll 文件。然后,引用将被正确添加。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接