1) Unable to execute Entity Framework Add-Migration with changes after the initial Add-Migration
Hopefully, my title is not as confusing as my explanation!!! <grin> I'm new to the Entity Framework and ran into a very interesting issue. I assume it's due to my lack of knowledge, but just in case it isn't I thought I'd document my issue and "work-around"/solution.
I'm running Visual Studio 2012 with Entity Framework 6.1. I'm using the Code First from Database as my approach. My SQL Server database had about 25 tables. I was just trying to use the Code First from Database approach to obtain my POCO classes for my database objects and the db context class that Entity Framework should "auto-majically" create for me.
I created a simple console application and then used the reverse engineer code first.
Right click on the project name
--> Entity Framework
--> Reverse Engineer Code First
Provide the appropriate server and database name. The Entity Framework will now create your POCO classes (usually under a Models folder in your solution. Additionally, it will create mapping classes under a Mapping sub-folder of the Models folder. It will also create a database context class (by deafult named "databasenameContext") in the Models folder.
Now I opened the Package Manager console and enabled migrations for my project.
PM> Enable-Migrations
Checking if the context targets an existing database...
Code First Migrations enabled for project ConsoleApplication5.
PM>
Next I obtained my base-level migration snapshot of my database
PM> Add-Migration v1.00
Scaffolding migration 'v1.00'
The designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration v1.00' again.
PM>
Now I assumed all I needed to do was make changes in my POCO classes and then run another Add-Migration to pick up the changes and get them applied to my database. WRONG!!!
I went to one of my POCO classes and just added a new column. A super tiny change, i.e.
public string testcolumn2 { get; set; }
PM> Add-Migration v1.01
Unable to generate an explicit migration because the following explicit migrations are pending: [201602080605348_v1.00]. Apply the pending explicit migrations before attempting to generate a new explicit migration.
PM>
Well, I tried applying the 201602080605348_v1.00 migration with the Update-Database command, but that also generated an error. The only way I found that I could create a new migration with my changes and get them applied was to do the following.
1) Copy my base migration, i.e. the one that apparantly been applied, 201602080605348_v1.00.cs, to a simple text file for safe keeping. The 201602080605348_v1.00.cs was in the Migrations folder of the project.
2) Replace the text in the 201602080605348_v1.00.cs with the following, i.e. just adding the column. Note you may have to change the namespace like I did if you are doing this multiple times. <grin>
namespace ConsoleApplication5.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class v100 : DbMigration
{
public override void Up()
{
AddColumn("dbo.board", "testcolumn2", c => c.String());
}
public override void Down()
{
DropColumn("dbo.board", "testcolumn2");
}
}
}
3) Now run the Update-Database command from the Package Manager console.
PM> Update-Database
Specify the '-Verbose' flag to view the SQL statements being applied
to the target database.
Applying explicit migrations: [201602080605348_v1.00].
Applying explicit migration: 201602080605348_v1.00.
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.
true to enable automatic migration.
You can use the Add-Migration command to write the pending model
changes to a code-based migration.
PM>
4) Now goto your database, I used SQL Server Management Studio, SSMS, and remove the column from the database table. Even though we got this error message, the operation/command still modified the database. We want to remove the column so we can run the entire process from within the Entity Framework so that all will be in synch.
5) Copy back the original/base migration text that you had copied to the text file and save it.
6) Now re-run the Add-Migration command from within the Package Manager console to pick up the new change.
PM> Add-Migration v1.01
Scaffolding migration 'v1.01'.
The Designer Code for this migration file includes a snapshot of your
current Code First model. This snapshot is used to calculate the
changes to your model when you scaffold the next migration. If you
make additional changes to your model that you want to include in this
migration, then you can re-scaffold it by running 'Add-Migration
v1.01' again.
PM>
Notice the new migration file that was added under the Migrations folder in the project.
7) Now run the Update-Database command still from within the Package Manager console to apply the changes and synch both the Entity Framework and your database.
References
https://msdn.microsoft.com/en-us/data/aa937723
https://msdn.microsoft.com/en-us/data/jj591621.aspx
2) Why when using EF Code First and Reverse Engineering an existing database do I get two constructors in my context class? I believe in the example below the first is ensuring my database is not recreated as I am connecting to an existing database, SixteenthSectionLegacy, and the second is identifying the connection string that is used in my app.config file...
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using EFReverseEngineerTest.Models.Mapping;
namespace EFReverseEngineerTest.Models
{
public partial class SixteenthSectionLegacyContext : DbContext
{
static SixteenthSectionLegacyContext()
{
Database.SetInitializer<SixteenthSectionLegacyContext>(null);
}
public SixteenthSectionLegacyContext()
: base("Name=SixteenthSectionLegacyContext")
{
}
public DbSet<board> boards { get; set; }
public DbSet<BOARD1> BOARDS1 { get; set; }
public DbSet<Classification> Classifications { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new boardMap());
modelBuilder.Configurations.Add(new BOARD1Map());
modelBuilder.Configurations.Add(new ClassificationMap());
}
}
}
3) Where you look for errors in entity framework code first reverse engineer? I am reverse engineering a very large database and found tables missing. Upon investigation I did find several that were missing primary keys. I'm trying trying to determine why the others were not created. Where can I look for errors, i.e. log file, etc.?
4) Attempting to use Code First with an existing database. Having issues with not all of the tables being imported as the primary key's don't follow the expected naming conventions so that EF can recongnize/identify the primary key. With a large number of tables it is not feasible to have to manually create all the POCO's so how can I get EF to import all the tables and create the base POCO's so that I can go in and tweak them after the fact???