EF move migration to new project - c#

I'm refactoring a project and want to move all the EF entities and the code-first migrations to a new project. I renamed the ContextKey in the _Migrations table to the new namespace. When running an Add-Migration, no new changes are detected (Up() and Down() are empty).
But when I remove the localdb, the db isn't re-created (it did before the move). Apparently only migrations created after the move are run (but it shouldn't).
How can I make sure all migrations (also the ones before the move) are run when creating a new db?
--edit--
Never mind :(
I dragged and dropped the existing migrations to the new project and renamed the namespaces in the migration.cs files, but forgot the code behind migration.Designer.cs

You can update all the ContextKey column values in the dbo._MigrationHistory table to match the new namespace and that's all.
For me i was moving all the code first models from ASP.NET MVC app to external Class library to share with other projects.
Below steps may help
check the dbo._MigrationHistory and you can see all records have
similar values which match the exact class of Configuration class
MyApp.Migrations.Configuration
2.(test step) run Update-Database from Package Manager Console with new class library selected and you will see for example below error
There is already an object named 'AspNetRoles' in the database.
update all the records in the ContextKey column of _MigrationHistory table to match the new namespace
MyApp.Domain.Migrations.Configuration

The reference table [__MigrationHistory] contains a ContextKey column. Unless otherwise valued, it maintains the value of the membership of DbContext namespace.
You can set a class that derives from dbMigrationsConfiguration and set the ContextKey value in the constructor.
public sealed class Configuration : DbMigrationsConfiguration<Your.Context>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
ContextKey = "PreviousValue";
}
protected override void Seed(Your.Context context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}

Related

How can I seed data to already created database?

I am creating a football manager game. I have used identity 2.0 as it will work well for my registration and login. I was able to add the extra tables that were needed but now I need to seed the data such as teams and players to these table. Any idea how to do so? The extra tables were created in the identity models using migrations. Here is a picture of the tables I am using.
In the Migrations folder, there is a file called Configuration.cs with the Seed method that you can use to create some seed data.
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//add roles
context.Roles.AddOrUpdate(p => p.Id,
new IdentityRole()
{
Id = EnumUtility<AspNetRoles>.GetAppRoleId(AspNetRoles.None),
Name = AspNetRoles.None.ToString()
});
}
Just run update-database and you should have data in your tables.
There are 2 Seed() methods available - one in certain initializers such as CreateDatabaseIfNotExist that is run whenever the database is created. The other is the migration Seed() which runs whenever you apply a migration via update-database.
Since it runs with every migration, you want to make sure you don't duplicate your data. You could do this by checking for existence:
if (!context.Teams.Any())
{
context.Teams.Add(new Team { Name = "Team A" });
context.Teams.Add(new Team { Name = "Team B" });
}
But there is a better way designed specifically for migrations called AddOrUpdate:
protected override void Seed(ApplicationDbContext context)
{
context.Teams.AddOrUpdate(
team => team.Id, // put the key or unique field here
new Team
{
Id = 1,
Name = "Team 1"
},
new Team
{
Id = 2,
Name = "Team 2"
});
context.SaveChanges();
}

Reset Entity Framework database to $InitialDatabase programmatically

I have Entity Framework (6.1.1) set up with migrations. I know I can run the following command in the Package Manager Console to reset the database to be completely empty:
Update-Database –TargetMigration: $InitialDatabase
But how can I do this from my code?
var configuration = new MyDbConfiguration();
configuration.TargetDatabase = new DbConnectionInfo(
"Server=MyServer;Database=MyDatabase;Trusted_Connection=True;",
"System.Data.SqlClient");
var migrator = new DbMigrator(configuration);
migrator.Update("201606030938116_InitialDatabase");
if you do not know your migration Id then you can just do:
migrator.GetDatabaseMigrations().First();
or:
migrator.GetLocalMigrations().First();
In your DbConfiguration you have to allow the auto dropping:
public class MyDbConfiguration: DbMigrationsConfiguration<MyDbContext>
{
public MyDbConfiguration()
{
this.AutomaticMigrationsEnabled = true;
this.AutomaticMigrationDataLossAllowed = true;
}
}
Update from #GTHvidsten:
Instead of getting the available migrations, you have to use this command: migrator.Update(DbMigrator.InitialDatabase);. But you also have to set the ContextKey property in MyDbConfiguration to match the one used in the Configuration object created by Package Manager. With both of these my database becomes empty.

Updating EF model in new DbContext instance

What is the best way to update an entity framework model in the database with two instances of a DbContext. For example i have a simple User model which is loaded in one DbContext but saved in another:
User model = null;
using(SampleDbContext dbContext = new SampleDbContext())
{
model = dbContext.User.Find(0);
}
model.UserName = "Test-User";
using(SampleDbContext dbContext = new SampleDbContext())
{
// Here is the place i want to save the changes of the model
// without loading it again from the database and set each property
// ...
dbCotnext.SaveChanges();
}
In my case i want to write some UserManager, which has Create, Update and Delete methods. I think creating one DbContext instance for the howle manager
is no solution, because i only want to save the changes of a specific model.
I also don't want to load the models for updating again from the database and settings each value from the source instance, like:
// Update user
using(SampleDbContext dbContext = new SampleDbContext())
{
// I don't want this:
var model = dbContect.User.Find(0);
model.UserName = sourceModel.UserName;
// ...
dbCotnext.SaveChanges();
}
Maybe my problem with manager classes is very simple, but i could not find any good solution.
P.S.: My manager classes are often singleton classes.
Thank you.
You could in your second DbContext do something like this:
using (SampleDbContext dbContext = new SampleDbContext())
{
dbContext.Entry(model).State = EntityState.Modified;
dbContext.SaveChanges();
}
This would save the changes you have made to the entity to the database. However I can't remember if dbContext.Entry queries the DB for the entity.

FluentMigrator Versioning Refresh Views

I am using Fluent Migrator for keeping the database updated. The Up and Down functions works perfectly. Next step is that I want views to be created. These I would like to run from an .SQL file which i have. I want this to be run after all migrations has been run, everytime.
What i have currently is:
var blah = new MigrationConventions();
var maintenanceLoader = new MaintenanceLoader(_migrate, blah);
maintenanceLoader.ApplyMaintenance(MigrationStage.AfterAll);
and a class
[Maintenance(MigrationStage.AfterAll)]
public class ViewMaintenance
{
public ViewMaintenance() {
var blah = 123;
}
}
This is not fired because in maintenanceLoader there are 0 elements that it can find. I am inserting the _migrate, which is defined like this:
var runnerContext = new RunnerContext(new TextWriterAnnouncer(UpdateText));
_migrate = new MigrationRunner(
Assembly.GetExecutingAssembly(),
runnerContext,
new SqlServerProcessor(
new SqlConnection(connectionString),
new SqlServer2012Generator(),
new TextWriterAnnouncer(UpdateText),
new ProcessorOptions(),
new SqlServerDbFactory()));
Why can't the Assembly.GetExecutingAssembly() be scanned, and find the [Maintenance(MigrationStage.AfterAll)] be found?
I would also like for the ViewMaintenance class to be able to run the Execute.Sql( that the Migration classes has.
I downloaded the source code and figured it out.
In the class I want the maintenance to be run, I need to inherit from the : Migration class, just like with migrations (duh..). It will then have access to everything it has access to in migrations, including Execute.Sql(.
When it is inherited from, the Reflection in Fluent Migrator will search for it, find it, and use the attribute that is set to run it after all migrations is run.
This part is not needed:
var blah = new MigrationConventions();
var maintenanceLoader = new MaintenanceLoader(_migrate, blah);
maintenanceLoader.ApplyMaintenance(MigrationStage.AfterAll);
Neat :)

Entity Framework Code First: Configuration.cs seed or custom initializer

I am working with the the Code First style of the Entity Framework for my first time. I want to set up some default data. The first approach I came across involved creating a custom initializer. I was headed this route but noticed after setting up migrations that it came with the Configuration.cs that already overrides the seed method just like the custom initializer.
internal sealed class Configuration : DbMigrationsConfiguration<Toolkit.Model.ToolkitContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(Toolkit.Model.ToolkitContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
So it seems there are two ways to accomplish this task. Can someone shed some light on what would be the recommended way of doing this? Or does it matter at all and I should just flip a coin?
The Configuration.cs Seed method will run every time your model changes to make sure that some specific data stays in your DB, or to even possibly to reset that data to a specified default setting.
The Custom Initializer's seed method, on the other hand, can be setup to run every single time the application loads, like in this code, which is currently in the Global.asax file of my MVC page:
Database.SetInitializer(new MyCustomInitializer<MyDbContext, Configuration>());
var db = new MyDbContext();
db.Database.Initialize(true);
The practical difference really comes into play after you deploy your application. The Custom Initializer will make sure that no user can destroy some data that's absolutely required in your program.

Categories

Resources