【问题标题】:Multi-targeting .net core 2.2 with .net 4.6.1多目标 .net core 2.2 和 .net 4.6.1
【发布时间】:2019-12-15 00:05:47
【问题描述】:

我已经开始使用从气象站收集数据的应用程序有一段时间了,为了使其跨平台,我使用了 .net core 2.2 mvc 和一些库。 即使数据保存在 mysql 数据库中,客户端最近请求从列表中选择的气象记录保存在本地访问数据库中。 为了实现这一点,我必须使用来自微软的合法数据库提供程序,在本例中是 EntityFrameworkCore.Jet。 起初我不知道存在兼容性问题导致

Could not load type 'System.Data.OleDb.OleDbConnection' from assembly 'System.Data,

在这部分代码中:

var msAccessDb = _msAccessRepo.InitializeDatabaseContext(connectionString);
msAccessDb.Database.OpenConnection();

现在我必须对我的 .csproj 文件进行一些多目标处理。我必须写什么样的语法? 我要做的第一件事是像这样更新 .csproj 文件:

<TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>

但是我所有的包,比如 automapper、Pomelo.EntityFrameworkCore.MySql、Entity Framework tools、NLog,都是在 netcoreapp2.2 框架下编译的。我得到各种错误,主要是 CS0234 和 CS234,即使 Itemgroup xml 部分中的 Condition 如下所示:

  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>    
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.2'">
    <PackageReference Include="AutoMapper" Version="9.0.0" />
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="EntityFrameworkCore.Jet" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.2.6" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.6">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
    <PackageReference Include="MySql.Data" Version="8.0.17" />
    <PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.17" />
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
    <PackageReference Include="System.Drawing.Common" Version="4.6.0" />
</ItemGroup>

我必须降级我的应用程序并从 .net 核心更改为 .net 框架吗?还是我在多目标中做错了什么?

提前感谢您的帮助。

[编辑]

根据下面的答案,我的 Project.Web.csproj 文件如下:

   <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
    <UserSecretsId>aspnet-myProject.Web-BBF62A3C-EE9E-4808-8924-F2BEA33CDBD6</UserSecretsId>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Drawing.Common" Version="4.6.0" />
  </ItemGroup>

  <ItemGroup  Condition=" '$(TargetFramework)' == 'net461'">
    <PackageReference Include="EntityFrameworkCore.Jet" Version="2.2.0" />
    <PackageReference Include="System.Data.OleDb" Version="4.6.0" />
  </ItemGroup>

  <ItemGroup  Condition=" '$(TargetFramework)' == 'netcoreapp2.2'">
    <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0"/>   
    <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0"/>    
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.6">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
    <PackageReference Include="AutoMapper" Version="9.0.0" />
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
    <PackageReference Include="MySql.Data" Version="8.0.17" />
    <PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.17" />
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
  </ItemGroup>

  <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.2'">
    <ProjectReference Include="..\myProject.DB\myProject.DB.csproj" />
    <ProjectReference Include="..\myProject.Lib\myProject.Lib.csproj" />
    <ProjectReference Include="..\myProject.LoggerService\myProject.LoggerService.csproj" />
  </ItemGroup>

当然,它开始给我构建错误,因为我必须为它们应用的不同框架应用条件。并不是说底部的单独库只是 .net core 2.2 项目,它们不针对任何其他框架。最初我已经删除了“条件”,但以下构建错误仍然存​​在(多达 850 个错误)。

The type or namespace name 'UserManager<>' could not be found

我知道我理解错了,或者 .net core 2.2 不支持多目标,而 .net 框架早于 4.6。

任何进一步的讨论来解决这个问题,或者证明这种多目标是行不通的,我们将不胜感激。

【问题讨论】:

    标签: c# .net .net-core entity-framework-core oledbconnection


    【解决方案1】:

    您只有 .NET Core 的包引用。如果它们适用,您应该为以下每一项设置一个项目组:

    • .NET Framework 程序集引用(带有目标框架Condition
    • 两个目标框架都需要的 Nuget 包引用
    • 仅 .NET Framework 需要的 Nuget 包引用(目标框架为 Condition
    • 仅 .NET Core 需要的 Nuget 包引用(使用目标框架 Condition

    此外,System.Data.OleDb.OleDbConnectionnot available natively in .NET Core。您需要引用System.Data.OleDb Nuget 包。

    请尝试从ItemGroup 中删除Condition=" '$(TargetFramework)' == 'netcoreapp2.2'" 并添加对System.Data.OleDb 包的引用。

    如果您需要参考框架独有的任何参考资料,请研究下面的示例。


    为了说明,这里是我的一个库中的包引用,它以 .NET Standard 2.0 和 .NET 4.8 为目标:

      <ItemGroup Condition="'$(TargetFramework)'=='net48'">
        <Reference Include="System.Configuration" />
        <Reference Include="System.Data.Linq" />
        <Reference Include="System.ServiceModel" />
        <Reference Include="System.ServiceModel.Web" />
        <Reference Include="System.Web.Extensions" />
      </ItemGroup>
    
      <ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
        <PackageReference Include="System.Diagnostics.EventLog" Version="4.6.0" />
      </ItemGroup>
    
      <ItemGroup>
        <PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
        <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
        <PackageReference Include="NodaTime" Version="2.4.7" />
      </ItemGroup>
    

    请注意我如何为框架 net48 引用 .NET Framework 程序集,为 netstandard2.0 引用一个 Nuget 包,为两个目标引用 3 个 Nuget 包。

    【讨论】:

    • .net 4.6.1 框架目标的唯一库是 System.Data.Oledb 和 EntityFrameworkCore.Jet。其余库的目标是 netcore 2.2 。这是否意味着如果我不想与 4.6.1 发生任何冲突,我必须将大多数系统库仅针对 netcoreapp 2.2?例如像 System.Generics 或 System.Web。
    • 您需要使用同样以 .NET Core 为目标的同名 Nuget 包,而不是使用 .NET Framework 中的 System.Data.Oledb。现在不要担心系统名称空间,除非它不能编译 - 它很复杂:) 参见例如stackoverflow.com/q/47119995/397817如果你有兴趣。
    【解决方案2】:

    我还没有理解一个项目中的多目标是如何工作的,所以对我有用的是在一个针对 .net 4.8 的单独 webapi 项目中创建特定的(访问数据库的连接)功能。控制器通过 httpClient 在内部调用 web api 方法并完成工作。 我知道这并不理想,但对于我们所拥有的时间限制,这是一个很好的解决方案。

    【讨论】:

      猜你喜欢
      • 2019-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-17
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      • 2017-07-26
      相关资源
      最近更新 更多