Entity Framework Core 2.0 not finding migration - entity-framework-core

I have a strange problem that my migration is not recognised by the EF Core 2.0
When running the Add-Migration command in PM, the MyFirstMigration classes are created inside the Migrations folder.
Context:
Protected Overrides Sub OnConfiguring(optionsBuilder As DbContextOptionsBuilder )
optionsBuilder.UseSqlite("Data Source=blogging.db")
End Sub
PM code:
PM> Add-Migration MyFirstMigration
To undo this action, use Remove-Migration.
PM> Update-Database
No migrations were applied. The database is already up to date.
Done.
When I check the dababase file, __EFMigrationsHistory table exists, but not the Blog table.
As you may suspect, running db.SaveChanges() throws an exception and tells me that table doesn't exists.
Running db.Database.Migrate() does nothing, but when I delete the db file and run db.Database.EnsureCreated(), correct database is created.
I must point out that __EFMigrationsHistory table is created empty, so I can immediately after Update-Database create the next migration and it will generate exactly the same code as in the first one.
I am using VS 15.3.5 and .Net 4.6.1 on WPF.
/ Best regards

Is it because Add-Migration is adding C# files to your VB.NET project? You can add them to a separate C# project, reference it from your DbContext assembly, and add update your OnConfiguring to the following.
optionsBuilder.UseSqlite("Data Source=blogging.db", Sub(x) x.MigrationsAssembly("MyCSharpProject"))

I had this issue where my migrations didn't contain any entities, then I noticed something that is not very obvious. The DbContext class looks at it's own member variables and then applies any fluent/attribute model properties to the generated migration.
So make sure your DbContext has something like this:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public virtual DbSet<Blog> Blogs { get; set; }
Also remember after making any changes that you need to generate a new migration. Which seems to work a bit different than before where update-database (PMC) used to always apply new changes.

Related

Why can I only enable code migrations if also enable automatic code migrations?

There was a breaking change so we decided to reset migrations, but now If we don't put the -EnableAutomaticMigrations option Enable-Migrations doesn't work.
My connection string is in my web project that is set as the startup project.
This are the steps we took:
First We deleted the Migrations folder and the database completely.
Then When we do:
enable-migrations
We get:
Checking if the context targets an existing database...
Unable to update database to match the current model because there are pending
changes and automatic migration is disabled. Either write the pending
model changes to a code-based migration or enable automatic migration.
Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to
enable automatic migration.
I don't understand this error, there is no database, there are no migrations, to what pending changes does it refer to? (I dont even have pending chanves in git)
If then We do
enable-migrations -EnableAutomaticMigrations
It works, but when We follow it with:
Add-Migration InitialCreation
It creates an Empty InitialCreation migration and it creates the database with the tables that correspond to my model. But doing this We can't get the scripts for creating the database for the first time. I don't get what is going on.
It seems the first time it uses some Automatic migration.
Why can't We enable-migrations without -EnableAutomaticMigrations?
Update
After talking with Steve Green, I think it could be useful to add part of my DbContext and Initializer
public class ApplicationDatabaseContext : DbContext
{
public ApplicationDatabaseContext()
: base("MyConnectionStringName")
{
Database.SetInitializer<ApplicationDatabaseContext>(new ApplicationDataInitializer());
if (!Database.Exists())
{
Database.Initialize(true);
}
}
And my DatabaseInitializer:
public class ApplicationDataInitializer : CreateDatabaseIfNotExists<ApplicationDatabaseContext>
{
protected override void Seed(ApplicationDatabaseContext context)
{
base.Seed(context);
CreateData(context);
}
private void CreateData(ApplicationDatabaseContext context)
{
//Add data here
context.SaveChanges();
}
}
First, make sure you have the initializer MigrateDatabaseToLatestVersion set.
Second, You should not need to enable automatic migrations. To reset migrations you don't have to delete the entire folder (especially if you've done some seeding or other customizations in the Configuration() class). Just delete the individual migrations then add a new baseline migration:
add-migration MyStartPoint -IgnoreChanges
This will take a snapshot with no code in the Up() since you don't really need that to generate a script to create the database. So now update-database -Script -SourceMigration $InitialDatabase should create a script you can use to create a new database.
Another option is to use an initializer like CreateDatabaseIfNotExist which will do exactly that.

Entity Framework Core Code First Update-Database does nothing

Im trying to use Entity Framework Core with a Code First approach.
So far I have developed some models and my context. I have then added the EntityFrameworkCore.Tools to work with migrations. I have defined my ConnectionString property in the appsettings like follows:
"Data": {
"ConnectionString": "Data Source=localhost;Initial Catalog=TestDb;User Id=user;Password=pass; Pooling=true; Max Pool Size=200; Min Pool Size=5"
}
(The user and password are correct btw)
In my DbContext then I have done the following:
public MyContext()
{
Database.EnsureCreated();
}
// ...
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connString = Startup.Configuration["Data:ConnectionString"];
optionsBuilder.UseSqlServer(connString);
base.OnConfiguring(optionsBuilder);
}
When I run the Add-Migration InitialDatabase it works fine, it creates my migration with its tables. And then when I launch the App, because of the Database.EnsureCreated() in MyContext it creates the database for me and it works fine.
The problem is I would like to control my migrations. So I would like to not rely on the EnsureCreated. The thing is when I execute Update-Database the command apparentely works (it doesnt show any error) but it does not create my database. I think I am missing a way to tell Update-Database where is my connection string. I know you can pass a parameter to it but I've seen people using it without parameters. How can I make this work?
Thanks!
You might need to set the ASPNETCORE_ENVIRONMENT variable first using the VS Package Manager and this command:
$env:ASPNETCORE_ENVIRONMENT='Debug'
then run:
Update-Database
If have configured the connection string in appsettings.debug.json, then it should create and initialize the database using your migration.

EF6 How to create missing mdf

I'm using EF6 with migrations enabled. I have a project that I decided to nuke and then re-pull from SVN. I didn't realize/know that the connected database (a localdb .mdf file stored in APP_DATA) was not checked in, and I'm not sure I want it to be anyway.
EF is not creating the datafile on startup, I tried changing the initializer to CreateDatabaseIfNotExists, but it's not working. I don't see any command line option to create it, and running "update-database" fails because the datafile doesn't exist. How do I create it?
I don't know if it's still relevant to you but
you can always remove your migrations folder and add a DropCreateDatabaseAlways seeder:
public class MyDbContext : DbContext
{
public MyDbContext() : base("SomeDBName")
{
Database.SetInitializer<MyDbContext>(new DropCreateDatabaseAlways<MyDbContext>());
}
}

Should we need to add explicit db migrations when using MigrateDatabaseToLatestVersion?

Recently I have faced issue with EF codefirst DB migrations. We have used MigrateDatabaseToLatestVersion for DB initializer.
Database.SetInitializer(new MigrateDatabaseToLatestVersion<TestDataContext, MyConfiguration>());
internal sealed class MyConfiguration : DbMigrationsConfiguration<TestDataContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
...
Issue is that - we accidentally ran old DB migration file using the below command :
Update-database -TargetMigration some_old_test_migration_cs_file
This caused us to loose latest entity schema changes and we were unable to push latest changes to database. After wasting a lot of time in troubleshoot, we fixed that issue by deleting migration history from the table __MigrationHistory.
My question is - Should we also add migration scripts whenever entity (code level) changes though we have enabled the automatic migrations?
What would be the best practice around this?
If you're using Automatic Migrations, you shouldn't need to code any explicit migrations yourself. Entity Framework will automatically update the database to match the current state of your entities when you create a context.

Resetting EF Code-First Migration State

I'm using EF 5. We are looking to convert our project to use code-first migrations.
Originally in our DBContext file we had an IDataBaseInitializer implementation that creates the DB if it doesn't exist (using context.Database.Create).
I wanted to test out the migration concept so I originally ran the commands:
Enable-Migrations -ProjectName MyProjectName
(This successfully created a Migrations folder with a Configuration.cs file)
Add-Migration Initial -ProjectName MyProjectName
(This successfully created a script file which matched my model classes)
At this point I wanted to try testing upgrade scenario so I created a tmp field on my model and reran the Add-Migration command which seemed to work as expected.
However at this point I wanted to reset my state. I've reverted all my changes in VS, removed the files from the Migrations folder from disk, tried removing the __MigrationsHistory table from my DB (and also completely deleting the DB). No matter what I do I can't get a new Add-Migration to create a script that includes my initial state. It always appears as this... this is my test value that I created originally.
public partial class Initial : DbMigration
{
public override void Up()
{
DropColumn("dbo.EventTrackingRecords", "TestValue");
}
public override void Down()
{
AddColumn("dbo.EventTrackingRecords", "TestValue", c => c.String());
}
}
I don't understand where it's keeping this initial information. The only other thing that I found interesting is that if I run my program after deleting the DB, it recreates my DB as I would expect based on the model, but it also creates a __MigrationHistory table! I don't understand how the context.Database.Create() command is doing this.
EF creates the __MigrationHistory table to keep your DB up to date, and warn you if it's not.
When you edit something in your models, and run the add-migration, you have to run update-database to be able to create a new migration. EF won't allow you to have pending migrations while creating new ones.
So, if you add a property to one of your models, and then create a migration, you have to update the database before creating a new migration where you delete the property.
Hope this helps.