Entity Framework 5 delete my database changing model - asp.net-mvc

I have an ASP.NET MVC 4 project with Entity Framework 5, .NET 4.5 and Visual Studio 2012.
In my solution I've put all the models in a project called Model, all the Repositories and my DbContext in one more project called Data.
I activate the migrations in the Data project with the Enable-Migrations command. I decide to handle them manually. If I create a new migration with the Add-Migration command everything works very well. If, for example, I add a new column to a table, it works fine. I can see the new column in the database schema and I see the new record into the _MigrationHistory table.
At this point, with the new column created, I need to add this column to the right model. So, i add this method to my code-first model class and I run the project.
It delete my database, and init it with the initial migration.
I can't tweak a model without loosing all data.
How I can avoid this behavior?
Thanks
UPDATE:
Configuration.cs
namespace NegoziazioneEventi.Data.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<NegoziazioneEventi.Data.NeDataContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(NegoziazioneEventi.Data.NeDataContext context)
{
}
}
}
Application_Start() in Global.asax
protected void Application_Start()
{
// init basic data on database
System.Data.Entity.Database.SetInitializer(new Models.InitData());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
_container = Bootstrapper.GetWindsorContainer();
}

I decide to handle them manually. If I create a new migration with the Add-Migration command everything works very well.
...
At this point, with the new column created, I need to add this column to the right model. So, i add this method to my code-first model class and I run the project.
That is completely wrong usage of migrations and it is also the reason why EF deletes your database. You must first add property to model and then add migration because EF needs to store correct data into _MigrationHistory table to match that record with the real meaning of that migration.
With your current approach EF runs the application and checks _MigrationHistory table but the record in the table doesn't contain information about your newly added property so EF believes that new change was done to your model and uses default strategy to delete database and create a new one reflecting your current model. You can turn off this behavior but you should start by using migrations correctly!
To turn off the behavior use:
Database.SetInitializer<YourDatabaseContext>(null);
You are using your own initializer which is most probably derived from wrong build-in initializer causing drop of your current database.

Related

EF 6 code-first migrations skipped

I have a entity framework 6 code-first project. I deleted my database and want to re-create it from scratch. When I run update-database some of the migrations do not run. That causes an error later because the database is not in the expected state.
This is the first migration that is skipped:
using System.Data.Entity.Migrations;
public partial class add_ConversationEntry_Type : DbMigration
{
public override void Up()
{
AddColumn("dbo.ConversationEntry", "Type", c => c.String(nullable: false));
}
public override void Down()
{
DropColumn("dbo.ConversationEntry", "Type");
}
}
It looks standard. It inherits from DbMigration and does nothing weird. The next 3 also are skipped and they all affect that dbo.ConversationEntry table.
With update-datebase -verbose it shows 'Applying explicit migrations:' and lists the migrations and these are missing from that list.
I have verified that these are also in the project file.
Where does update-database get the list of migrations?
Why would some be skipped?
The best thing to do in this scenario is to create an idempotent script of all the migrations and see what Entity Framework is trying to do:
update-database –SourceMigration $InitialDatabase -Script
This should have everything needed to create the database, the __MigrationHistory table and to consecutively apply your migrations.
If all other databases you care about are up to date, you could simply reset the migrations. Yet another option would be to switch the initializer to createdatabaseifnotexists which would create a new database based on your model.
Each entity framework migration consists from three files
entity class .cs
and additional code-behind files
metadata file .Designer.cs
database model snapshot .resx
Make sure <timestamp>_dd_ConversationEntry_Type.Designer.cs file is not missing and is included in your project.
easy easy
Make sure the build action is "Compile" and don't forget to mark this answer as "Correct Answer".
enter image description here

MVC EF (Code First) - Creating relationship with AspNetUsers and Custom Tables

new to MVC and EF. Trying to achieve the following:
A new site with individual user accounts
Create a DB table "Leagues" whereby when creating a new league the LeagueAdmin is an ApplicationUser
I followed this tutorial to try to achieve what i wanted. When i start the application I am able to register new users without issue. However, when I go to create a new league I get the following error:
"Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations."
I have tried many fixes i've read about but they tend to lead me down a path of increasingly complex errors. I feel like this should be simple enough that i'd like to understand this error first before tackling the next.
VS Project Source is here
Most probably, your database does not contain a _MigrationHistory table.
Add this code to your DbContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}
Go to Package Manager Console by following View -> Other Windows -> Package Manager Console
And write following commands:
enable-migrations
add-migration InitialCreate
update-database
Alternatively;
You can add this code to your DbContext;
static LeagueContext()
{
Database.SetInitializer<LeagueContext>(
new DropCreateDatabaseAlways<LeagueContext>());
}

How to create a single migration for a specific model using C# ASP.net MVC 5

I am trying to develop a small application using ASP.NET MVC 5.
I am using Entity Framework with a code first approach.
To get started, I created my first model and then followed the steps below to create the table in the database
I opened the Package Manager Console
I executed Enable-Migrations
I executed Add-Migration InitilizeModel1Table
Finally, to create the table I executed Database-Update
In step 3 created a migration called datetime_InitilizeModel1Table which created the code that will create the table automatically.
In step 4, it applied the create table command and created the table in the database as expected.
Now, I created 3 more models and what I like to do is create a separate migration for each to keep my code separated.
So I thought I would start again at step 2 and so the following
Add-Migration InitilizeModel2Table
Add-Migration InitilizeModel3Table
Add-Migration InitilizeModel4Table
Database-Update
But the command Add-Migration InitilizeModel2Table is creating an empty migration without the code that is needed to create the tables.
Here is an example of one
namespace App.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class InitilizeModel2Table : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
}
How can I create a new migration for each model without having to manually write the migration script to create the tables?
The problem here was that you weren't adding your models to the context, hence EF did not detect the changes.
EF links the state of the model to the migration via the __MigrationHistory table/the migration files themselves. It compares the latest value in __MigrationHistory to the current state of your context, if they are different then a new, non-empty migration will be created when you run Add-Migration X.
Here are a couple of resources describing code-first migrations.
I am by no means an EF expert, so I may be slightly off in the details here.

EF not seeding database on creation

I am using Entity Framework to create and seed my database using Code First and the MigrateDatabaseToLatestVersion initializer. The issue I am having is when I launch the ASP.NET MVC app without a database create EF will create the database but will not seed on the first run through. If I kill iisexpress and relaunch the app after creating the database my seeds go in fine. I would expect my seeds to be ran after the database gets created but I don't even hit a break point in my seeds method on the first run through. I hit break points on the second run through without problems but it is annoying to have to run the app twice after killing the DB just to get my seeds to work.
Below is my Configuration class:
public sealed class Configuration : DbMigrationsConfiguration<CompassDb>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(CompassDb context)
{
ModuleSeed.Seed(context);
PermissionGroupSeed.Seed(context);
var permissions = PermissionSeed.Seed(context);
var roles = RoleSeed.Seed(context, permissions);
UserSeed.Seed(context, roles, permissions);
OcmPluginSeed.Seed(context);
SCACSeed.Seed(context);
ModuleConfigurationSeed.Seed(context);
}
}
I am calling this in my Global.asax file.
Database.SetInitializer(new MigrateDatabaseToLatestVersion<CompassDb, Configuration>());
using (var db = new CompassDb())
{
db.Database.Initialize(true);
}
I did have a query to get a version number from the db on page load to create the database but calling the initializer directly seems a little cleaner. I was having the issue before when I was making a DB call through EF as well. I moved away from the DB call because I am only using EF for the automatic DB creating and migration then I switch to Dapper for any database communication.
I found this post here where people were having the same issue as me but it doesn't seem like it was ever resolved.
UPDATE
I found out that the issue is related to my migration files. I updated the primary keys of all my models from int to long and had to delete my current migration files. After deleting the files everything started working as normal, the database would be created and seeded on the same request. I then created my initial schema migration and am back at the same issue where the database does not seed until the 2nd time launching the site. I am using ELMAH in the project and have to update the first migration file to execute the sql file that is included when installing ELMAH via nuget. This could be related to the issue and I will do more testing to see if this is the cause.
I think I had the same or similar problem. Try to make a manual initializer. It's clean, simple and short. See this example:
Public Class CustomDbInit
Implements IDatabaseInitializer(Of MyContext)
Public Sub InitializeDatabase(context As MyContext) Implements System.Data.Entity.IDatabaseInitializer(Of MyContext).InitializeDatabase
If Not context.Database.Exists Then
context.Database.CreateIfNotExists()
' Some other processes, such as WebMatrix initialization if you're using SimpleMembership like I do
End If
End Sub
End Class
Then on the Global.asax Application_Start method, initialize it like this:
Dim context As New MyContext()
If Not context.Database.Exists Then
Database.SetInitializer(New CustomDbInit())
context.Database.Initialize(False)
End If

You custom database IdentityDbContext

I was trying to develop an application and created my own database which then was reflected to an entity model using database first. So I now already have let's say myOwnDBContext.
Then I thaught it wuld be a nice idea to mix it with the classes generated by IdentityDbContext. But when i just changed the connection string in IdentityModel like this
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("myOwnDBConnectionString")
{
}
}
The tables were not generated as I would expect in myOwnDB but instead I received the following error.
The entity type ApplicationUser is not part of the model for the
current context.
Is there a way I can mix the defualt database of IdentityDbContext with my own databse?
I'm not sure if this can work without using EF migrations, but I do have it working with migrations. Specifically, two DbContext derived classes (one for custom entities, one derived from IdentityDbContext).
For the migrations I had to enable-migrations from the package manager console for both contexts and use the -MigrationsDirectory parameter to place the two sets of migrations into distinct folders (a new feature for EF6).
Then when running update-database the tables are created properly for each context. The update-database command will need a -ConfigurationTypeName parameter to specify the exact migration to use.

Resources