Cannot add migration with ASP.net Core 2 - c#

I'm building a new project using ASP.net Core 2 and EntityFrameWorkCore 2.1.0 and I began to build the database structure. Now I have to make my first Migration to get my database ready and when I execute 'Add-Migration Init' into the Package Manager Console I got this error:
The current CSharpHelper cannot scaffold literals of type 'Microsoft.EntityFrameworkCore.Metadata.Internal.DirectConstructorBinding'. Configure your services to use one that can.
Also I tried this documentation https://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/migrations and the message I got is:
Unable to create an object of type 'ApplicationDbContext'. Add an implementation of 'IDesignTimeDbContextFactory<ApplicationDbContext>' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
I also followed this article without any success.
If I try without Microsoft.AspNetCore.Identity.EntityFrameworkCore 2.0.2 and with a simple 2 tables structure I'm able to make it work.
So now I need your help...

Make sure that you have the required NuGet packages installed:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Design

I found some reasons why we can get hard time to use migration with the latest version of ASP.net Core 2 at this time.
First of all, if you just migrate from an old project which is not built from ASP.net Core at all, you will have to add a Context Factory to make Migrations work. Here my own Context Factory:
public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
builder.UseSqlServer("Server=(local)\\SQLEXPRESS;Database=yourdatabase;User ID=user;Password=password;TrustServerCertificate=True;Trusted_Connection=False;Connection Timeout=30;Integrated Security=False;Persist Security Info=False;Encrypt=True;MultipleActiveResultSets=True;",
optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(ApplicationDbContext).GetTypeInfo().Assembly.GetName().Name));
return new ApplicationDbContext(builder.Options);
}
}
If you divided your project into layers for architecture purpose, add the Context Factory inside the Repository Layer or in the same library where your DbContext is.
Secondly, before any attempt to add a migration, you must set the selection of “set as startup project” on the repository library or where your DbContext is.
Then, those are the packages you need to use for migration:
Microsoft.AspNetCore.Identity.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.SqlServer
That’s all!
Be careful when you add other packages because they can break the Migration system. As an example, if you use a Unit of Work & Repositories Framework like URF and install URF.Core.EF.Trackable -Version 1.0.0-rc2, you will no longer be able to add migration. Instead use URF.Core.EF.Trackable -Version 1.0.0-rc1. I guess this can happen with many other packages as well.
Finally, read this article will be helpful. It’s a little outdate but it can help people out there.
Cheers

How do you arrange the main method in "Program.cs"?
This error can be amenable to a old initialization pattern.
From the Asp Net migrations guidelines:
The adoption of this new 2.0 pattern is highly recommended and is
required for product features like Entity Framework (EF) Core
Migrations to work. For example, running Update-Database from the
Package Manager Console window or dotnet ef database update from the
command line (on projects converted to ASP.NET Core 2.0) generates the
following error:
Unable to create an object of type ''. Add an implementation of 'IDesignTimeDbContextFactory' to the
project, or see https://go.microsoft.com/fwlink/?linkid=851728 for
additional patterns supported at design time.
Check at this link of the correct implementation

In my case, the dbcontext was different in Startup within ApplicationDbContext class.
services.AddDbContext<DbContext>
to
services.AddDbContext<ApplicationDbContext>

Related

How can I use a DbContext from a different assembly for my migrations?

I have multiple projects in a solution. For clean architecture reasons, I want to keep the DbContext in Infrastructure project, but my Startup Project is the API project. So the Program.cs is in the API project.
I tried to specify that I wanted to use my context from the Infrastructure proect like this:
builder.Services.AddDbContext<DzbcDbContext>(opt => opt.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly("DZBC.Infrastructure") )); // <- tried this
But it's not working. The error still tells me it's looking for the DbCOntext in the API project.
All similar answers are either old or don't work in .net core 6.
It's solved by forcing it in Developer PowerShell.
Navigate to the project folder where you have your DbContext (in my case Infrastructure). From there use this:
dotnet ef migrations add initial --startup-project "../DZBC.API/DZBC.API.csproj"
dotnet ef database update --startup-project "../DZBC.API/DZBC.API.csproj"
But use the .csproj path of your Startup project.

Using a separate migration project for F# data layer

I'm trying to setup migrations for my EF Core project on F# .NET 4.7.2. Currently I have the following data context:
type MyContext =
inherit DbContext
new() = { inherit DbContext() }
new(options: DbContextOptions<MyContext>) = { inherit DbContext(options) }
[<DefaultValue>]
val mutable apples: DbSet<AppleEntity>
member x.Apples
with get () = x.apples
and set v = x.apples <- v
Setting up my initial migration using Add-Migration Initial -Context Application.MyContext told me that F# is not a supported language for generating migrations, which is why I set up a C# project with a reference to the F# project.
However, when running the add migration command from this project, EF Core cannot find my context class: No DbContext named 'Application.MyContext' was found.
On Microsofts documentation about using a separate migration project, the following tip is stated:
If you have no existing migrations, generate one in the project containing the DbContext then move it. This is important because if the migrations assembly does not contain an existing migration, the Add-Migration command will be unable to find the DbContext.
But this is not a possibility for me, given that the context is in an F# project. Anyone have a clue on where to go from here?
EF is not F# friendly and AFAIK it's not in their near plan to improve the support for other languages. If you need migrations you have to use another framework like DbUp or another ORM like Linq2DB, Dapper. Easier option is to define the data layer in C# and reference it from other F# project
I managed to work around the issue by creating a C# version of MyContext and running the Add-Migration command. Then I deleted it and changed the reference in both MyContextModelSnapshot.cs and Initial.designer.cs to my F# data context.

Accessing SQL from Entity Framework Core Queries in ASP.NET Core

In a post in the last week or so, someone made reference to a post: http://rion.io/2016/10/19/accessing-entity-framework-core-queries-behind-the-scenes-in-asp-net-core/
The blog outlined using internals of EF to show the generated SQL for a given EF query. Having a tool like this is invaluable, and will help my EF dev team to write better code. However, as it uses internal and unsupported code, it will not build using EF 2.1.4. The reference to RelationalQueryModelVisitor is now gone, and the code will not build.
I am using using .net core 2.1 as well.
Is there another or similar approach available?
Thanks.
Use the class in this link, which does work in .NET Core 2.1. Yes, I know you said you tried it, but I just tried it and it worked, so there must be something else going wrong in your project. Tell us the compiler error you are getting and we can help further.
Here is what I did:
Created a new ASP.NET Core project and made sure it's targetting .NET Core 2.1.
Added Microsoft.EntityFrameworkCore version 2.1.4 from NuGet.
Created an IQueryableExtensions class and pasted the code.
It compiles.
The RelationalQueryModelVisitor class does still exist in .NET Core 2.1. The documentation shows it is still there (notice the "Entity Framework Core 2.1" in the top left of the docs) and the current source code on GitHub still shows it there.
Would using their logging functionality be sufficient?
https://learn.microsoft.com/en-us/ef/core/miscellaneous/logging
public static readonly LoggerFactory MyLoggerFactory
= new LoggerFactory(new[] {new ConsoleLoggerProvider((_, __) => true, true)});
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(MyLoggerFactory) // Warning: Do not create a new ILoggerFactory instance each time
.UseSqlServer(...);
It's in the Microsoft.EntityFrameworkCore.Relational nuget package.

EF7 migration generator is ignoring context parameter

I have recently migrated my EF7 project from DotNet Core 1.0.0 to Version 1.1.0, now I have trouble with creating the database migrations.
In my project I have multiple contexts, the tool dotnet-ef is providing a command line parameter to distinct between these contexts in order to create a separate migration for each context.
When I try to create the migrations for the context "AuditLogContext" with the command
dotnet ef migrations add Initial --context 'Some.Namespace.AuditLogContext' --output-dir './Migrations/AuditLogMigrations'
then it fails, telling me
The name 'Initial' is used by an existing migration.
when I'm trying to create the migration with another name, say Initial2, the migration get created but for the wrong context.
In the folder
./Migrations/AuditLogMigrations
are new files named
20170212122451_Initial2.cs
20170212122451_Initial2.Designer.cs
CoreContextModelSnapshot.cs
I expect the file AuditLogContextModelSnapshot.cs instead.
Does anybody have solved this issue before?
I found the reason for this problem.
I have multiple contexts in my project, every context expects parameters. So migrations builder expects a factory for every context.
In my case one class, implements all factories, now there is a bug that the concrete order of the interfaces is used to determine which migrations are created.
public class Program : IDbContextFactory<CoreContext>, IDbContextFactory<AuditLogContext>, IDbContextFactory<LockContext>
This snippet will create migrations for the CoreContext
public class Program : IDbContextFactory<AuditLogContext>, IDbContextFactory<CoreContext>,IDbContextFactory<LockContext>
and the snippet will create migrations for the AuditLogContext.
It's a bit annoying but if you know how to create the migrations it's ok.

Enable Migrations from context on different assembly

So basically I've two projects on the same solution. One of the projects its a class library where I have the all the Models and the Database Context class. The other one is a Web API. I want to use Nuget to Enable-Migrations on the Web API project but I always get the "No context type was found in the assembly Pr.WebApi.
So far I've tried:
Enable-Migrations -ContextTypeName Pr.ClassLibrary.Models
Any Ssuggestions?
When theres no data to store in a database in your WebAPI-Project, you dont need Entity Framework at all in this project. If you store data over your Class library, you can use the context from the class library project.
You will use Enable-Migrations in the Package Manager Console. Make sure that the default project on the top of the package manager console is set to your class library. That is the only project you need to enable the migrations on.
Enable-Migrations should be invoked in your class library...

Categories

Resources