当作为dotnet cli工具启动时,出现“System.Data.SqlClient在此平台上不受支持”的错误

12

我们有一个简单的netcore 2.2控制台应用程序,使用来自Microsoft.EntityFrameworkCore的DbContext。 在控制台上启动时,它按预期工作。

然而,我们决定将其用作dotnet CLI工具。 它的.csproj文件包含:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AssemblyName>dotnet-dbupdate</AssemblyName>
    <Title>Db Updater</Title>
    <Version>1.0.1</Version>
    <PackageId>DbUpdater</PackageId>
    <Product>DbUpdater</Product>
    <PackageVersion>1.0.1</PackageVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
  </ItemGroup>
</Project>

我们使用dotnet pack将其打包到Nuget服务器。然后在目标文件夹中,我们得到了以下的.csproj文件:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="DbUpdater" Version="1.0.1" />
  </ItemGroup>
</Project>

从这个文件夹中我们可以恢复并执行:

dotnet restore
dotnet dbupdate

突然,在 DbSet ToList 方法调用时,我们收到以下错误信息:

System.Data.SqlClient is not supported on this platform

在将其作为dotnet CLI工具启动时,肯定存在问题。然而,我们尚未找到此问题的原因以及如何解决它。在网上搜索没有给我们任何尝试的想法。


在打包之前,你的代码是否能够正常运行?例如,在源目录中运行 dotnet run 或在 IDE 中点击“运行”按钮。 - Jamie Taylor
啊,是的。抱歉。 - Jamie Taylor
在SqlServer之外添加整个EntityFramework的引用会解决什么问题? <PackageReference Include =“Microsoft.EntityFrameworkCore”Version =“2.0.0”/> - Legion
@Legion,不幸的是它并没有。 - horgh
@PanagiotisKanavos 我实际上降级到了2.0版本,因为在互联网上找到一个想法,认为它可能适用于旧版本。但是它既不能与最新的稳定版本(2.2.4)一起工作,也不能与可用的预览版本一起工作。而且总是出现同样的错误。 - horgh
显示剩余15条评论
6个回答

0
我遇到了同样的问题,这是因为使用了错误版本的System.Data.SqlClient,在我的情况下,应用程序是使用.NET 4.6构建的,而类库是在.Net Standard 2.0中,它依赖于System.Data.SqlClient。 在生产环境中替换了适当版本的System.Data.SqlClient(在我的情况下是.NET 4.6)后,问题得到解决。

0

尝试指定用于CLI的.NET版本:

dotnet dbupdate --fx-version 2.2.4

如果上述方法不起作用,也可以尝试使用其他已安装的版本(2.2.2)。

实质上,为了避免不兼容性问题,运行CLI的.NET版本、控制台应用程序的目标SDK以及依赖项的包版本都必须匹配。


@horgh,你能否上传一个可重现的代码到GitHub上,这样我们就可以从那里查看了吗? - Siavas

0
如果你想在 Linux 操作系统上运行它,只需确保使用正确的目标运行时发布你的解决方案。例如,如果你想在 Red Hat Enterprise Linux 上运行它,请选择 linux-x64。

0

刚刚在 local.settings.json 中添加了 v2 兼容性:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "FUNCTIONS_V2_COMPATIBILITY_MODE": "true"
  }
}

-1

如果您正在使用Asp.net core 2.2开发项目,请注意以下问题:

当您更改目标项目设置(从启动设置到cli)或类型(从类库到标准库)或从nuget部分删除某些依赖项时,编译器无法将dll文件移动到目标文件夹中。(编译器错误,微软在vs 2019的最后两个修订版中进行了更正)。您可以尝试手动移动它,但不能保证成功。在这种情况下,降级可能是一个解决方案。

Asp.net框架核心编译器主要查看项目文件,其他引用模块优先级较低。dotnet restore和dotnet update无法根据我们的更改提供设置。例如,如果您删除了一个包并执行了-dotnet restore命令,则需要查看Visual Studio的nuget依赖项部分。它们可能仍然存在。因此,您可以尝试将Microsoft.EntityFrameworkCore.SqlServer放置在最终项目的最终文件中。

以上是解决方案

自包含应用程序。 在这种情况下,如果您正在使用与另一个应用程序相关的DLL(例如SQLBase驱动程序),或者您可以通过隔离这些DLL将其他NuGet依赖项放入您的应用程序中。这使您能够从系统中的其他资源中工作。在您的情况下,您应该为Microsoft.EntityFrameworkCore.SqlServer执行此操作。
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>

请在不同意的情况下写下评论。

-1
请注意,ToList()方法在使用相应的DLL时会触发SQL命令,例如第一次。因此,简单地说,您的错误表明Microsoft.EntityFrameworkCore.SqlServerSystem.Data.SqlClient存在依赖项不匹配,您知道第二个第一个的依赖项。第二个也有一些依赖项,但我认为您的问题并不是来自它。
检查打包后的默认引用(版本),并尝试更改为合适的引用。不幸的是,我们无法重现您的问题,因此请尝试此解决方案并告诉我们结果。 编辑 根据dotnet-pack documentation
打包的项目的NuGet依赖项将被添加到.nuspec文件中,因此在安装包时可以正确解析它们。项目对项目的引用不会被打包在项目内。如果您有项目对项目的依赖关系,则必须每个项目一个包。
默认情况下,Web项目无法打包。要覆盖默认行为,请将true属性(位于内)添加到您的.csproj文件中。
我认为您需要在.csproj文件中包含以下内容:
<ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
    <PackageReference Include="System.Data.SqlClient" Version="4.4.0"/>
</ItemGroup>

另外,根据dotnet-pack文档的说明,不再需要使用dotnet restore

从.NET Core 2.0开始,您不必运行dotnet restore, 因为所有需要还原的命令(如dotnet builddotnet run)都会隐式地运行它。 在某些情况下,执行显式还原仍然是有效的命令。


请问您能详细描述一下我们如何在打包后检查默认引用吗? - horgh
@horgh,请查看 https://github.com/dotnet/corefx/issues/34580 中的有用指南,例如 dotnet --info 命令和其他一些指南。我相信存在不匹配的情况。 - Amirhossein Mehrvarzi
@horgh 我知道,我的意思是在你看不到的地方打包后引用发生了变化。请注意,.net 可以从任何他喜欢的地方获取引用,而不是你想要的地方或第一次寻址的地方,除非你在打包之前通过某些方式(如 本地复制 或更改配置)断言。因此,唯一的方法是再次指向正确的引用以成功运行 dotnet 命令。 - Amirhossein Mehrvarzi
那么,您能告诉我在打包之前明确指定必要的软件包的正确方法吗?这样,在进行dotnet pack后它们就不会被覆盖了。 - horgh
@horgh 请查看我的修改,希望能解决问题。 - Amirhossein Mehrvarzi
显示剩余2条评论

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