Click here to Skip to main content
15,886,110 members
Articles / Programming Languages / C#

Various Strategies to Initialize Database in Entity Framework

Rate me:
Please Sign up or sign in to vote.
4.89/5 (14 votes)
7 Jul 2014CPOL3 min read 61.8K   26   7
In this article, I am going to discuss various database initialization strategies in Entity Framework

Introduction

This is the second article of this series. In our first article, we have seen how to start with code first approach in Entity Framework? You can read it here: Code First approach in Entity Framework. Ok, so we got the idea of code first and other approaches and learned when and how it will help in various development scenarios. In discussion, we have seen that it is required to write code at first in code first approach and then database will get generated. The approach is very clear and straightforward. Now, let’s think of the scenario when we have written code and generated database and then we decided to change something in the database. It may be adding a new property (column, in terms of database relational schema) or deletion of old one. Or we might think of changing relationship between tables. Now, database is already created previously, so shall we modify the existing database and create a new one? Entity Framework has given four options to handle the situation. They are:

  • Create database if it does not exist
  • Create database always
  • Create database when model changes
  • Customize

In this article, we will discuss one by one and know how to implement in Entity Frame code first approach. Create database if it does not exist. This is the attempt for first time run, generally at first the database did not create and we can set the setting in context class, so when the database is not present, the setting is useful. Have a look at the following code:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace CodeFirst
{
    public class Person
    {
        [Key]
        public int PersonId { get; set; }
        [Required]
        [MaxLength(10)]
        public string Name { get; set; }
        public string surname { get; set; }
    }

    public class TestContext : DbContext
    {
        public TestContext()
            : base("DBConnectionString")
        {
            //Create database always, even If exists
            Database.SetInitializer<TestContext>(new  CreateDatabaseIfNotExists<TestContext>());
        }
        public DbSet<Person> Students { get; set; }
    }
}

The implementation is very simple, we have created Person model and TestContext class to initialize the database using code first approach. Please note that we are passing the connection string through constructor, the connection string should configure in web.config file in the same application. Here is mine.

C#
<connectionStrings>
  <add name="DBConnectionString"
  connectionString="Data Source=SERVERNAME;Initial Catalog=PersonDB;Integrated Security=true"
  providerName="System.Data.SqlClient"/>
</connectionStrings>

Just configure your connection string according to your environment and once you run the application, you will see that it has created database as below:

Create Database Always

In this approach, database will create always whether it already exists or not? So, in each run of the code, it will drop the database if it exists and will create one brand new database. So, when brand new database will create obviously the old data will get lost if exist anything. So, definitely be sure your database seeding code is available always in this approach in development environment. Here is the configuration for creating database always approach. The model (Person) is the same in this example too.

C#
public class TestContext : DbContext
    {
        public TestContext()
            : base("DBConnectionString")
        {
            //Create database always, even If exists
            Database.SetInitializer<TestContext>(new  DropCreateDatabaseAlways<TestContext>());
        }
        public DbSet<Person> Students { get; set; }
    }

If Model Changes

This is another fantastic approach to generate database, in my concern. The database will get generated when model in code will not match with database model. Here is the code to set the approach.

C#
public class TestContext : DbContext
    {
        public TestContext()
            : base("DBConnectionString")
        {
            //Create database always, even If exists
            Database.SetInitializer<TestContext>(new DropCreateDatabaseIfModelChanges<TestContext>());
        }
        public DbSet<Person> Students { get; set; }
    }

Custom Initialize

This is the last and most important one. The approach is very much flexible and the full control is in the developer’s hand. Developer can decide when database will get generated and new database will create according to the new code. Have a look at the below implementation:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace CodeFirst
{
    public class Person
    {
        [Key]
        public int PersonId { get; set; }
        [Required]
        [MaxLength(10)]
        public string Name { get; set; }
        public string surname { get; set; }
    }

    public class PersonDBInitializer : DropCreateDatabaseAlways<TestContext>
    {
        protected override void Seed(TestContext context)
        {
            base.Seed(context);
        }
    }

    public class TestContext : DbContext
    {
        public TestContext()
            : base("DBConnectionString")
        {
            //Create database always, even If exists
            Database.SetInitializer<TestContext>(new PersonDBInitializer());
        }
        public DbSet<Person> Students { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var ctx = new TestContext())
            {
                new PersonDBInitializer().InitializeDatabase(ctx);
            }
        }
    }
}

In this approach, we have introduced another class called DBInitializer class and call SetInitialise method by creating object of PersonDBInitializer class.

Seeding Data into Database

This is the bonus topic I wanted to introduce the mechanism to set some default data in brand new database. Sometimes, it’s very much useful when we want some default data along with newly created database. Have a look at the below code:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace CodeFirst
{
    public class Person
    {
        [Key]
        public int PersonId { get; set; }
        [Required]
        [MaxLength(10)]
        public string Name { get; set; }
        public string surname { get; set; }
    }

    public class PersonDBInitializer : DropCreateDatabaseAlways<TestContext>
    {
        List<Person> persons = new List<Person>();
        public PersonDBInitializer()
        {
            persons.Add(new Person { Name = "sourav", surname = "kayal" });
            persons.Add(new Person { Name = "foo", surname = "bar" });
        }
        protected override void Seed(TestContext context)
        {
            foreach (Person p in persons)
            {
                context.Students.Add(p);
            }
            context.SaveChanges();
            base.Seed(context);
        }
    }

    public class TestContext : DbContext
    {
        public TestContext()
            : base("DBConnectionString")
        {
            //Create database always, even If exists
            Database.SetInitializer<TestContext>(new PersonDBInitializer());
        }
        public DbSet<Person> Students { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var ctx = new TestContext())
            {
                new PersonDBInitializer().InitializeDatabase(ctx);
            }
        }
    }
}

This code will set the default data in Person table.

Border Line

In this article, we have seen various approaches to initialize database in code first approach. Hope it will help you. In the next article, I am interested in discussing inheritance in code first approach in Entity Framework.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer DELL International
India India
I am software developer from INDIA. Beside my day to day development work, i like to learn new technologies to update myself. I am passionate blogger and author in various technical community including dotnetfunda.com , c-sharpcorner.com and codeproject. My area of interest is modern web technology in Microsoft stack. Visit to my personal blog here.

http://ctrlcvprogrammer.blogspot.in/

Comments and Discussions

 
GeneralNice Article Pin
Alireza_13629-Feb-16 11:10
Alireza_13629-Feb-16 11:10 
GeneralMy vote of 1 Pin
shatl8-Jul-14 8:20
shatl8-Jul-14 8:20 
QuestionWhere's the long term value. Pin
Mike Schudel8-Jul-14 5:06
Mike Schudel8-Jul-14 5:06 
SuggestionRe: Where's the long term value. Pin
edmolko14-Jul-14 6:22
edmolko14-Jul-14 6:22 
SuggestionMigrations Pin
edmolko8-Jul-14 4:28
edmolko8-Jul-14 4:28 
GeneralMy vote of 5 Pin
Carsten V2.08-Jul-14 1:29
Carsten V2.08-Jul-14 1:29 
GeneralMy vote of 5 Pin
Volynsky Alex8-Jul-14 0:25
professionalVolynsky Alex8-Jul-14 0:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.