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.
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’s need to
write code at first in code first approach and then database will get generate.
The approach is very clear and straight forward. Now, let’s think the scenario
when we have written code and generated database and after then we decided to
change something in database. It may be adding a new property (column ,in terms
of database relational schema) or deletion of old one Or we might think to
change relationship between tables. Now, database is already created previously,
so shall we modify the existing database and create new one? . Entity Framework
has given four options to handle the situation. They are.
- Create database If not exists
- Create database always
- Create database when model change
- customize
In this article we will discuss one by one and know how to
implement in Entity Frame code first approach.
Create
database if not exists
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 on below code.
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 exhists
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 same application. Here
is mine.
<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 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 exist 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 create
database always approach. The model (Person) is same in this example too.
public class TestContext : DbContext
{
public TestContext()
: base("DBConnectionString")
{
//Create database always, even If exhists
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 generate when model in code will not match
with database model. Here is the code to set the approach.
public class TestContext : DbContext
{
public TestContext()
: base("DBConnectionString")
{
//Create database always, even If exhists
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 developer’s hand. Developer can decide when
database will get generate and new database will create according to new code.
Have a look in below implementation.
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 exhists
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 introduce another class called
DBInitializer class and calling 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 on
below code.
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 exhists
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 next
article I am interested to discuss inheritance in code first approach in Entity
Framework.
No comments:
Post a Comment