Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add new table to an existing database using Code First approach in EF 6 and MVC 5

I know this should be simple, but I was unable to find correct tutorial or explanation on web on this subject. There is a lot of videos and posts about adding new column to an existing table, using code first approach, but I can not find any with step by step explanation on how to add whole new table into existing database. Which is weird, I was pretty sure that I will find many examples. Maybe my search criteria is bad. So if anybody has any good link or video, please share.

What I'm trying to do is to add table Post into existing Default Database, created by MVC 5 project. I've made model class first, named it Post and it has a simple definition:

public class Post
    {
        [Key]
        public int PostId { get; set; }
        public string PostText { get; set; }
        public byte[] ImagePost { get; set; }
        public byte[] FilePost { get; set; }
        public string TextPost { get; set; }
        public string UserId { get; set; }
    } 

Then I have first doubts. I know I should create DbContext, but if I want to hit an existing database, should I use existing DbContext, already created by default in Web.config file like this:

<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-StudentBookApp-20150114035149.mdf;Initial Catalog=aspnet-StudentBookApp-20150114035149;Integrated Security=True"
      providerName="System.Data.SqlClient" />

Or I should use all new DbContext created for Post class?

Anyhow I've tried it both, but no success. When I created this new context I was doing following in PMC:

Enable-Migrations
Add-Migration "PostMigration"
Update-Database

Usually, or all goes well, but I don't get any new table in database, or I get an error: AspNetUsers already exists, and AspNetUsers is one of auto-created tables that I've changed by adding new columns to it.

Update: My context right now is in seperated class named PostContext and it looks like this:

public class PostContext : DbContext
{
    public PostContext() : base("name=PostContext")
    {
    }

    public DbSet<Post> Posts { get; set; }
}

Second try:

Since my first approach didn't gave any result. I've tried doing what's described in this link. Adding mapping to my project:

I've crated new class PostConfiguration for mapping:

public class PostConfiguration : EntityTypeConfiguration<Post>
    {
        public PostConfiguration() : base()
        {
            HasKey(p => p.PostId);
            ToTable("Post");

            HasOptional(p => p.PostText);
            ToTable("Post");

            HasOptional(p => p.ImagePost);
            ToTable("Post");

            HasOptional(p => p.TextPost);
            ToTable("Post");

            HasOptional(p => p.FilePost);
            ToTable("Post");

            HasRequired(p => p.UserId);
            ToTable("Post");
        }
    }

In the class Post I've added context class too PostContext with modelBuilder variable as they've suggested in listed link above:

 public class PostContext : DbContext
    {
        static PostContext()
        {
            Database.SetInitializer(new DropCreateDatabaseIfModelChanges<PostContext>());
        }

        public DbSet<Post> Posts { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Properties()
                        .Where(p => p.Name == "Key")
                        .Configure(p => p.IsKey());

            modelBuilder.Configurations.Add(new PostConfiguration());
        }

   }

I've run all PMC commands again, and still no success, table Post is missing from default database.

like image 595
nemo_87 Avatar asked Jan 15 '15 07:01

nemo_87


1 Answers

What has happened here is that you had existing database tables before Migrations where enabled. So Entity Framework thinks that ALL your database objects need to created, this could be seen by opening up your PostMigration migration file.

The best way is to trick EF into to doing the initial migration with every before you added the Post table and then do the Posts migration after.

Steps

  1. Comment out the Posts in the DBContext so EF doesn't know about posts

    //public DbSet<Post> Posts { get; set; }
    
  2. Enable Migrations

    Enable-Migrations
    
  3. Add an initial migration with all tables prior to your changes

    Add-Migration "InitialBaseline" –IgnoreChanges
    
  4. Now update the database, this will create a MigrationHistory table so that EF knows what migrations have been run.

    Update-Database
    
  5. Now you can uncomment the line in 1 to "Do your change"

  6. Create a new migration with the addition of Posts

    Add-Migration "PostMigration"
    
  7. Now do an update... and hopefully it should all work.

    Update-Database
    

Now that migrations are all setup and they are baselined future migrations will be easy.

For more information I found this link useful: http://msdn.microsoft.com/en-us/data/dn579398.aspx

like image 179
Oliver Avatar answered Nov 11 '22 05:11

Oliver