C# 为什么根据.NET标准编译.NET Framework项目时缺少此NuGet依赖项?

C# 为什么根据.NET标准编译.NET Framework项目时缺少此NuGet依赖项?,c#,.net,dll,.net-standard,dll-reference,C#,.net,Dll,.net Standard,Dll Reference,我有一个VisualStudio解决方案,有3个项目 顶层是.NET Framework 4.6.1控制台应用程序(项目a)。 它依赖于.NETFramework 4.6.1类库(项目B)。 项目B依赖于.NET标准2.0类库(项目C) 我在项目C中有一些代码使用System.Data.SqlClient(NuGet软件包版本4.6.1) 由于以下已知问题,我还将System.Data.SqlClient作为NuGet依赖项添加到项目B(.NET Framework类库) 这是场景1,在构建解决

我有一个VisualStudio解决方案,有3个项目

顶层是.NET Framework 4.6.1控制台应用程序(项目a)。 它依赖于.NETFramework 4.6.1类库(项目B)。 项目B依赖于.NET标准2.0类库(项目C)

我在项目C中有一些代码使用System.Data.SqlClient(NuGet软件包版本4.6.1)

由于以下已知问题,我还将System.Data.SqlClient作为NuGet依赖项添加到项目B(.NET Framework类库)

这是场景1,在构建解决方案时,System.Data.SqlClient被复制到项目A的/bin/Debug文件夹中,并且应用程序成功运行

场景1的代码在这里

然而,对于场景2,我现在向项目a添加了一个项目引用,这样它现在也直接引用/依赖于项目C(即.NET标准类库)以及项目B。这模仿了我在遗留应用程序中需要做的事情

清理、重建和运行。现在项目A的/bin/Debug文件夹中缺少System.Data.SqlClient,在运行时出现异常“System.IO.FileNotFoundException:'无法加载文件或程序集'System.Data.SqlClient”

为什么System.Data.SqlClient没有复制到/bin/Debug

请注意,我已选择不将.NET Framework项目迁移到PackageReferences以解决此问题,因为我需要在不可行的大型传统ASP.NET解决方案中实现此功能

我希望添加对projectc的引用不会有什么影响,除了(如观察到的)它会导致更多类型的转发DLL被复制到/bin/Debug文件夹。但我不希望System.Data.SqlClient现在丢失。

对原始问题的评论基本上回答了这个问题

在场景1中,我们在构建日志中看到了这一点

3>  Dependency "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
3>      Resolved file path is "C:\dev\testing\TestDependencyFlowsNetStandard\TestDependencyFlows.Library\bin\Debug\System.Data.SqlClient.dll".
对于场景2,MSBuild不会尝试使用项目B的
bin
目录,生成日志显示了这一点,如

此洞察提供了修复方案2的解决方案

使用本文中的解决方案,通过在.NET标准项目C的.csproj中的
中添加
true
,System.Data.SqlClient将复制到该.NET标准项目的
bin
目录,然后MSBuild能够找到并复制到最终生成输出文件夹

编辑-上述建议不起作用,因为在运行实际应用程序时,推送到输出目录的DLL用于错误的平台,并且与.NET Framework不兼容

作为进一步的信息,引用的生成日志可以在VisualStudioIDE中按照以下步骤获得

System.Data.SqlClient
添加到Project A的建议是可行的,但这是我想要避免的,因为在真正的单片遗留应用程序中,有许多与Project A等价的东西需要添加(而不是简单地将其添加到Project B的下一个级别)。

我将在这里重复我的评论,因为它被认为是一个有效的答案

MSBuild
日志将其生成输出详细度设置为level
detailed
,提供了更多关于发生什么的细节

情景1(A参考B,B参考C)

生成日志显示项目A成功地从项目B的
\bin\debug
文件夹解析了其
System.Data.SqlClient
依赖关系,并将其复制到本地。
(由于项目B是一个.NET Framework类库,它的NuGet依赖项确实会被复制到它的
bin
文件夹中。)

场景2(A参考B和C,B参考C)

构建日志提到项目A试图从
NET Standard
项目C(以及一些众所周知的文件夹)中解析其
System.Data.SqlClient
依赖关系,但不再从项目B中解析。
(因为项目C是一个
NET标准
项目,它不会将其
NuGet
依赖项复制到其
bin
文件夹中。)
所有这些尝试都失败,并显示消息,文件在这些位置不存在

Dependency "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
  Could not resolve this reference. Could not locate the assembly "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". 
  Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
  For SearchPath "C:\...\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0".
      Considered "C:\...\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.winmd", but it didn't exist.
      Considered "C:\...\TTestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.dll", but it didn't exist.
      Considered "C:\...\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.exe", but it didn't exist.
      ...


解决方案可以是将
System.Data.SqlClient
NuGet包也添加到项目A中

“2此处列出的版本代表NuGet用于确定给定.NET标准库是否适用的规则。虽然NuGet认为.NET Framework 4.6.1支持.NET标准1.5到2.0,但在使用.NET Framework 4.6.1项目中为这些版本构建的.NET标准库时存在一些问题。对于需要使用此类库的.NET Framework项目,我们建议您将该项目升级到目标.NET Framework 4.7.2或更高版本。“()。可能需要一些字符串来支持您的建议@sineauthy。我已尝试将.NET Framework项目升级到4.7.2,但遗憾的是,上面提到的问题仍然存在。将
System.Data.SqlClient
NuGet包也添加到项目A中应该可以解决此问题。对于场景2,
MSBuild
日志显示它没有无法从project
C
解析此依赖项,因为
.NET Standard
项目未将其依赖项复制到
bin
文件夹中,因此缺少此依赖项。对于方案1,
MSBuild
从项目B解析此依赖项,该操作成功。
Dependency "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
  Resolved file path is "C:\...\TestDependencyFlows.Library\bin\Debug\System.Data.SqlClient.dll".
Dependency "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
  Could not resolve this reference. Could not locate the assembly "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". 
  Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
  For SearchPath "C:\...\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0".
      Considered "C:\...\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.winmd", but it didn't exist.
      Considered "C:\...\TTestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.dll", but it didn't exist.
      Considered "C:\...\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.exe", but it didn't exist.
      ...