how to setup EFcore database first in separate class library in ASP.NET Core MVC application? - asp.net-core

I have a DB and I want to add a separate class library for entity framework to access my data but when I run scaffold command it makes a DB model in my web application.

You should select your Data project as default project in package manager console.
Be careful, you have ef core references in data.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RuntimeFrameworkVersion>2.0.5</RuntimeFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.0-preview3-35497" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.0-preview3-35497"/>
<PackageReference Include="System.Data.Common" Version="4.2.1" />
</ItemGroup>
</Project>
I realized that there are some errors in ClassLibrary projects. You can take a look at them:
https://learn.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#targeting-class-library-projects-is-not-supported
https://github.com/dotnet/cli/issues/8735
https://github.com/aspnet/EntityFrameworkCore/issues/10298

#ibrahimozgon's answer is right and helped me. However, I encountered a few errors in the DbContext class on the way which he didn't mention how to solve:
'EntityTypeBuilder' does not contain a definition for 'ToTable' and no accessible extension method 'ToTable' accepting a first argument of type 'EntityTypeBuilder' could be found (are you missing a using directive or an assembly reference?
and
'KeyBuilder' does not contain a definition for 'ForSqlServerIsClustered' and no accessible extension method 'ForSqlServerIsClustered' accepting a first argument of type 'KeyBuilder' could be found (are you missing a using directive or an assembly reference?
To resolve these errors in DbContext class, open up package manager console again and select the default project to be the class library. Enter these commands one by one:
- Install package: Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 2.2.4 (or whichever latest version)
- Install package: Install-Package Microsoft.EntityFrameworkCore.Relational -Version 2.2.4 (or whichever latest version)
- If errors persist try: Install-Package or Update-Package Microsoft.EntityFrameworkCore.Tools (or whichever latest version)

Related

Can't create EF migrations after installing .NET 6

I've just installed .NET 6 SDK and updated all my projects to use target net6.0, but when I try to create a new migration with the dotnet tool I get:
.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<ApplicationIcon>assets-logo.ico</ApplicationIcon>
<RootNamespace>LC.Assets</RootNamespace>
<Authors>Stein Lundbeck</Authors>
<Company>Lundbeck Consulting</Company>
<Product>LC Assets</Product>
<Copyright>2021</Copyright>
</PropertyGroup>
<ItemGroup>
<Content Include="assets-logo.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LC.Components.Core\LC.Components.Core.csproj" />
<ProjectReference Include="..\LC.Components\LC.Components.csproj" />
</ItemGroup>
</Project>
It was not possible to find any compatible framework version The framework 'Microsoft.NETCore.App', version '2.0.0' (x64) was not found.
The following frameworks were found:
6.0.0 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
You can resolve the problem by installing the specified framework and/or SDK.
I've updated the dotnet-ef tool to version 6.0.0, so I don't know what it is that still target the 2.0.0 version.
Tool 'dotnet-ef' was successfully updated from version '5.0.4' to version '6.0.0'.
Any ideas?
I just ran into the exact same issue.
Rather than installing Microsoft.NETCore.App 2.0.0., I installed the Entity Framework Core Design package:
dotnet add package Microsoft.EntityFrameworkCore.Design
It made the error go away for me.
Note: I came upon the solution after remembering that following the EF Getting Started guide (https://learn.microsoft.com/en-us/ef/core/get-started/overview/first-app?tabs=netcore-cli) had me install the Design package and didn't throw the error when I followed the guide.
I had this problem recently after upgrading to .NET6.
The solution for me was to follow the link in the error message and install Microsoft.NETCore.App 2.0.0.
https://dotnet.microsoft.com/download/dotnet/2.0/runtime
I'm guessing that the upgrade to 6 removed this framework as it is considered legacy ... BUT ... is still used (or marked as a required dependency somehow) in the dot net tools.
The solution for me was installing EntityFrameworkCore.Design as suggested by #Thomas Z.
dotnet add package Microsoft.EntityFrameworkCore.Design
As well, making sure the path of the db is correct when creating the ef migration. It won't work if the path is dynamically created.

Cannot find `SignalR` in `Microsoft.AspNetCore.App` in .NET Core 2.2?

I'm not so sure why this can be a problem, I've just revised some documentation about SignalR in ASP.NET Core and it seems to mean that I don't have to install any additional package (already have Microsoft.AspNetCore.All and Microsoft.AspNetCore.App referenced after creating a new ASP.NET Core project (version 2.2).
I've even tried Googling and found this blog post: https://wakeupandcode.com/real-time-asp-net-core-web-apps-with-signalr/#dep
It was written on Dec 23 2018, and the author does confirm that we don't need to install any additional package.
Well so it's really playing on me, making me have a feeling of being stupid, not so sure why I cannot use SignalR in my project (I'm not intending to install any additional package, which I think should work for me), just wonder why it's not already available. The following code does not compile:
using Microsoft.AspNetCore.SignalR;
It reports that SignalR does not exist in the namespace Microsoft.AspNetCore right in the project that has Microsoft.AspNetCore.All and Microsoft.AspNetCore.App.
Actually I cannot find the Microsoft.AspNetCore.SignalR when expanding the references tree.
The documentation says nothing about where to import the module (which means it should already be available). As I said the project targets .NET Core 2.2. Could you explain to me something could be wrong here?
PS: My project is a Web API (not MVC) project.
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.9.4" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.2.0" />
</ItemGroup>
Usually, project templates have outdated libraries. Use the NuGet package manager to update references to recent versions and try again. It should help.

What is the default version of the nuget package when referenced with PackageReference in .NET Core project?

I am trying to learn and understand nuget and msbuild in .NET Core by examining and manually editing project files (.csproj in .NET Core 2.2).
So when I create WebApi project, the .csproj file looks like this:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
</Project>
Notice that there is no Version attribute specified for the first PackageReference.
Now if I specify it to be the latest stable version 2.2.3 like this:
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.3" />
I get build warning NETSDK1071 which says:
A PackageReference to 'Microsoft.AspNetCore.App' specified a Version
of 2.2.3. Specifying the version of this package is not recommended.
For more information, see https://aka.ms/sdkimplicitrefs
This warning is not shown when Version attribute is omitted so I was wondering how is nuget package Version resolved when not set explicitly?
Also, how does dotnet build knows which version of a nuget package is recommended with the current project settings?
From the link in the warning, you can learn that it is not a regular package, but Meta-package.
It's mean that this package depends on your TargetFramework, and this is mean that when you target to a specific framework that installed in your machine (as SDK), the package will be taken from the specific SDK.

EntityFrameworkCore 2.x and PrivateAsset="All"

I'm building an .NetCoreApp1.1 webapi. We have the typical business and data layer assemblies broken out. When we added EntityFrameworkCore 2.x to the data access project, I was able to test functionality that went across projects. But the webapi stopped working! We were no longer able to start the app. program.cs-main failed with the exception:
System.MissingMethodException: "Method not found: 'System.IServiceProvider >MicrosoftExtensions.DependencyInjection.ServiceCollectionContainerBuilderExtens>ions.BuildServiceProvider...'
Articles indicated a package type mismatch but I couldn't find anything out of place. The EntityFrameworkcore in the data layer was suspect since it was version 2.0.0-preview1-final. In VS2017 there is a new feature to mark packages as private to the assembly. This made sense to do this with EF in the data layer so I opened the project and marked them PrivateAsset="All"
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.0-preview1-final" **PrivateAssets="All"** />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0-preview1-final" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0-preview1-final" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="2.0.0-preview1-final" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0-preview1-final" PrivateAssets="All" />
<PackageReference Include="WindowsAzure.Storage" Version="8.1.4" />
</ItemGroup>
This solved my problem. I was able to rebuild and run the webapi application. But, now my test failed with:
Message: Test method
ACMEAppTests.AppTests_FileManagerSave.FileManager_SaveFile threw exception: >System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.EntityFrameworkCore, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
This makes no sense. The assembly is there. So it seems I can't get both applications working at the same time. The errors make no sense to me. There seems to be little information on the PrivateAsset="All" feature for packages. I found this description:
Tip
A private package reference (PrivateAssets="All") means this dependency is local to the current project. For example, if Project A has a build only dependency and Project B depends on A, dotnet restore will not add A's build-only dependencies into Project B.
reference
.Net Command Line Tools
How to resolve this? Figure out why the webapi stopped working (Method not found) or debug the missing assembly reference that isn't, from what I can tell, missing?
All help appreciated.
You can't mix ASP.NET Core 1.1 with EF Core 2.0. They share some common dependencies (e.g. Logging, DependencyInjection, etc.) which means all your Microsoft.* package versions need to more-or-less align.
See the documentation about PrivateAssets. Adding PrivateAssets="All" prevents your data layer's dependencies from propagating into your app. Hence, you get could not load assembly errors.

Could not find 'UserSecretsIdAttribute' on assembly 'ef'

I am using ASP.NET Core 1.1 and I have the following on startup:
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.AddUserSecrets();
I am using csproj file instead of JSON where I added:
<PropertyGroup>
<UserSecretsId>8844d677-223b-4527-a648-387a65933d55</UserSecretsId>
</PropertyGroup>
But when I run the command:
dotnet ef migrations add "InitialCommit"
I get the error:
An error occurred while calling method 'ConfigureServices' on startup class 'Startup'. Consider using IDbContextFactory to override the initialization of the DbContext at design-time. Could not find 'UserSecretsIdAttribute' on assembly 'ef, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"
Any idea why?
You have run into this issue: https://github.com/aspnet/Configuration/issues/543
The solution is to change your call .AddUserSecrets() to .AddUserSecrets(Assembly assembly)
See this announcement about how deprecating project.json required a breaking change to user secrets: https://github.com/aspnet/Announcements/issues/209
I had this issue also. My solution was to install the nuget package Microsoft.Extensions.Configuration.UserSecrets.
It finally worked for me when I changed a version of package in .csproj:
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="1.1.2" />
to:
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="1.1.1" />