问题
I had started on an application on gathering data from meteorological stations for some time now and to make it cross platform I used .net core 2.2 mvc along with some libraries. Even though the data is saved in a mysql db, the client recently requested that selected meteo records from a list, to be saved in a local access db. To achieve that I had to use the legit database provider from microsoft which in this case is EntityFrameworkCore.Jet. I didn't know that there was a compatibility issue at first resulting in a
Could not load type 'System.Data.OleDb.OleDbConnection' from assembly 'System.Data,
in this part of the code:
var msAccessDb = _msAccessRepo.InitializeDatabaseContext(connectionString);
msAccessDb.Database.OpenConnection();
Now it comes to the point where I have to do some multi-targeting on my .csproj files. What kind of syntax do I have to write? The first thing that I have to do is update the .csproj file like so:
<TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
But all my packages like automapper, Pomelo.EntityFrameworkCore.MySql, Entity Framework tools, NLog, compile under the netcoreapp2.2 framework. I get all sorts of errors mainly CS0234, and CS234 even with the Condition inside the Itemgroup xml part like so:
<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>
Must I downgrade my app and change from .net core to .net framework? Or am I doing something wrong in my multi-targeting?
Thank you in advance for your help.
[EDIT]
Based on the answer below, my Project.Web.csproj file is the following:
<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>
Of course it started giving me build errors because I had to apply conditions for the different frameworks they apply. Not that the separate libraries at the bottom, are .net core 2.2 projects only and they do not target any other framework. Originally I had removed the 'Condition' but the build errors such as the following persist (as many as 850 errors).
The type or namespace name 'UserManager<>' could not be found
I know that I understood something wrong, or maybe the .net core 2.2 is not supported to be multi-target with .net framework as old as 4.6.
Any further discussion to solve this, or prove that this multi-targeting will not work, wiil be appreciated.
回答1:
You only have package references present for .NET Core. You should have an item group for each of the following if they apply:
- .NET Framework assembly references (with a target framework
Condition
) - Nuget package references which are required for both target frameworks
- Nuget package references which are needed for .NET Framework only (with a target framework
Condition
) - Nuget package references which are needed for .NET Core only (with a target framework
Condition
)
Additionally, System.Data.OleDb.OleDbConnection
is not available natively in .NET Core. You will need to reference the System.Data.OleDb Nuget package.
Please try removing Condition=" '$(TargetFramework)' == 'netcoreapp2.2'"
from the ItemGroup
and add a reference to the package System.Data.OleDb.
If you need to take any references which are unique to a framework study my example below.
Here, for illustration, are the package references from a library of mine which targets .NET Standard 2.0 and .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>
Note how I reference .NET Framework assemblies for framework net48
, one Nuget package for netstandard2.0
, and 3 Nuget packages for both targets.
回答2:
I have yet to understand how multi-targeting in one project works, so what worked for me, was to create the specific (connection to access db) feature in a separate webapi project targeted in .net 4.8. The controller calls the web api method internally via httpClient and does the job. I know that it is not ideal but for the time constraints that we have, it is a good solution.
来源:https://stackoverflow.com/questions/58192348/multi-targeting-net-core-2-2-with-net-4-6-1