EF7 migration generator is ignoring context parameter - c#

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.

Related

Circular dependency when generating dbcontext migrations into another assembly

As the name suggests I have multiple projects, and one of the project contains the dbcontext and all the models. So, I want to generate migrations from that project and put all generated migrations into another assembly (because I have multiple db providers for the same dbcontext, and one way is to move all migrations in different assemblies, so, i dont have problems later.).
Project containing the dbcontext and other stuff is not my main project, is just a class library.
The structure of the solution looks like below:
MyProject.DbContext
MyProject.DbContext.Migrations
MyProject
So, I reference the project MyProject.DbContext.Migrations from MyProject.DbContext to make the dotnet ef ... work, and I run this command:
dotnet ef migrations add InitMySql --project ..\MyProject.DbContext.Migrations
This will work fine as long as I do sth like this:
optionsBuilder.UseLazyLoadingProxies().UseMySql(configuration.ConnectionString, ServerVersion.AutoDetect(configuration.ConnectionString), builder =>
{
builder.CommandTimeout(configuration.CommandTimeout);
builder.UseNewtonsoftJson();
builder.MigrationsAssembly("MyProject.DbContext.Migrations");
});
But, now I have a big problem, the project MyProject.DbContext.Migrations needs also reference to MyProject.DbContext because of the new class created 'MyDbContextModelSnapshot' which has an attribute at the top: [DbContext(typeof(MyDbContext))] etc. Now I run into a circular dependency issue!
How is this supposed to be solved ?
I am currently using Asp.Net core 5, but I think this will happen for any version, seems more like a design limitation...

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.

Cannot add migration with ASP.net Core 2

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>

Entity Framework Change Assembly Model not recognised

I have an MVC 5 website with using the entity framework V6.1.1. The entity framework DbContext classes and models were originally all inside the website project. This project had 3 DbContext classes and 3 databases. I had also enabled migrations and applied one one of these databases.
I have now moved all the entity framework classes including the models and the migrations to a separate project and since then I have been getting the following error for the databases where a migration has been applied:
The model backing the 'MyContext' context has changed since the
database was created.
The database has not changed. I have also made sure the Context Key is the same in both the Configuration constructor and the database __MigrationHistory table.
I have also been seeing the following behavior:
I do a Get-Migrations in the package manager console and the correct migrations are returned. Then I am able to build and run the site and no error message is shown until I next make a change and build the solution.
If I change the Context Key in either the database of the Configuration constructor there is no error, but I assume that the migrations are not all being picked up.
I have also been looking through all the migrations files including the designer files and the namespaces all match up. If anyone could shed some light on this problem it would be much appreciated.
You should put this in the constructor of 'MyContext'
> Database.SetInitializer<YourDbContext>(null);

Not able to instantiate a context from all project within a solution

I have a solution where there are following projects:
a context and entities developed under code-first approach.
A class library that present some business objects. the objets are using the EF context and its object for a DataAccess needs.
The solution has unit test of the business objects
I am able to execute my unit test successfully.
Now I have added a MVC 5 project where I would like to inject my business object. I have created a controller and view and put the same peace of code which has been passed in one of my unit test and also added the project web config proper entity framework and connnection strings sections. When I am executing the code I am facing the follwing error:
Migrations is enabled for context 'DatabaseContext' but the database
does not exist or contains no mapped tables. Use Migrations to create
the database and its tables, for example by running the
'Update-Database' command from the Package Manager Console.
When I am debugging my code I see that I am getting throug theese instructions
Database.SetInitializer(new ModelContextStrategy());
and
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
but still my result is negative, although everething works fine in my unit testss...
in case I am doing the unit tests first the db is get created and all unit test are through, and then I am starting the MVC application I am getting:
The model backing the 'DatabaseContext' context has changed since the
database was created. Consider using Code First Migrations to update
the database
What I am missing or doing wrong? (specific nuget packages installation for the mvc project? )
the problem was solved as soon a I enabled the entity framework for my MVC project
Install-Package EntityFramework -Version 6.1.0

Categories

Resources