Professional Documents
Culture Documents
Entity Framework Code First Migrations
Entity Framework Code First Migrations
Entity Framework Code First Migrations
Sign in
Community
Forums
Documentation
Data Developer Center > Learn > Entity Framework > Get Started > Code First Migrations
24/4/2014
Run the Install-Package EntityFramework command Add a Model.cs file with the code shown below. This code defines a single Blog class that makes up our domain model and a BlogContext class that is our EF Code First context
Now that we have a model its time to use it to perform data access. Update the Program.cs file with the code shown below.
u s i n gS y s t e m ; u s i n gS y s t e m . C o l l e c t i o n s . G e n e r i c ; u s i n gS y s t e m . L i n q ; u s i n gS y s t e m . T e x t ; n a m e s p a c eM i g r a t i o n s D e m o { c l a s sP r o g r a m { s t a t i cv o i dM a i n ( s t r i n g [ ]a r g s )
http://msdn.microsoft.com/en-us/data/jj591621 2/12
24/4/2014
Run your application and you will see that a MigrationsCodeDemo.BlogContext database is created for you. If SQL Express is installed (included in Visual Studio 2010) then the database is created on your local SQL Express instance (.\SQLEXPRESS). If SQL Express is not installed then Code First will try and use LocalDb ((localdb)\v11.0) - LocalDb is included with Visual Studio 2012. Note: SQL Express will always get precedence if it is installed, even if you are using Visual Studio 2012
http://msdn.microsoft.com/en-us/data/jj591621
3/12
24/4/2014
(LocaDb Database)
Enabling Migrations
Its time to make some more changes to our model. Lets introduce a Url property to the Blog class.
http://msdn.microsoft.com/en-us/data/jj591621 4/12
24/4/2014
p u b l i cs t r i n gU r l{g e t ;s e t ;} If you were to run the application again you would get an InvalidOperationException stating The model backing the 'BlogContext' context has changed since the database was created. Consider using Code First Migrations to update the database ( http://go.microsoft.com/fwlink/?LinkId=238269). As the exception suggests, its time to start using Code First Migrations. The first step is to enable migrations for our context. Run the Enable-Migrations command in Package Manager Console This command has added a Migrations folder to our project, this new folder contains two files: The Configuration class. This class allows you to configure how Migrations behaves for your context. For this walkthrough we will just use the default configuration. Because there is just a single Code First context in your project, Enable-Migrations has automatically filled in the context type this configuration applies to. An InitialCreate migration. This migration was generated because we already had Code First create a database for us, before we enabled migrations. The code in this scaffolded migration represents the objects that have already been created in the database. In our case that is the Blog table with a BlogId and Name columns. The filename includes a timestamp to help with ordering. If the database had not already been created this InitialCreate migration would not have been added to the project. Instead, the first time we call Add-Migration the code to create these tables would be scaffolded to a new migration.
24/4/2014
We need to scaffold a migration to take care of the new Url property we have added. The Add-Migration command allows us to give these migrations a name, lets just call ours AddBlogUrl. Run the Add-Migration AddBlogUrl command in Package Manager Console In the Migrations folder we now have a new AddBlogUrl migration. The migration filename is pre-fixed with a timestamp to help with ordering
n a m e s p a c eM i g r a t i o n s D e m o . M i g r a t i o n s { u s i n gS y s t e m ; u s i n gS y s t e m . D a t a . E n t i t y . M i g r a t i o n s ; p u b l i cp a r t i a lc l a s sA d d B l o g U r l:D b M i g r a t i o n { p u b l i co v e r r i d ev o i dU p ( ) { A d d C o l u m n ( " d b o . B l o g s " ," U r l " ,c= >c . S t r i n g ( ) ) ; } p u b l i co v e r r i d ev o i dD o w n ( ) { D r o p C o l u m n ( " d b o . B l o g s " ," U r l " ) ; } } } We could now edit or add to this migration but everything looks pretty good. Lets use Update-Database to apply this migration to the database. Run the Update-Database command in Package Manager Console Code First Migrations will compare the migrations in our Migrations folder with the ones that have been applied to the database. It will see that the AddBlogUrl migration needs to be applied, and run it. The MigrationsDemo.BlogContext database is now updated to include the Url column in the Blogs table.
Customizing Migrations
So far weve generated and run a migration without making any changes. Now lets look at editing the code that gets generated by default.
http://msdn.microsoft.com/en-us/data/jj591621 6/12
24/4/2014
Its time to make some more changes to our model, lets add a new Rating property to the Blog class
p u b l i cc l a s sP o s t { p u b l i ci n tP o s t I d{g e t ;s e t ;} [ M a x L e n g t h ( 2 0 0 ) ] p u b l i cs t r i n gT i t l e{g e t ;s e t ;} p u b l i cs t r i n gC o n t e n t{g e t ;s e t ;} p u b l i ci n tB l o g I d{g e t ;s e t ;} p u b l i cB l o gB l o g{g e t ;s e t ;} } We'll also add a Posts collection to the Blog class to form the other end of the relationship between Blog and Post
p u b l i cv i r t u a lL i s t < P o s t >P o s t s{g e t ;s e t ;} We'll use the Add-Migration command to let Code First Migrations scaffold its best guess at the migration for us. Were going to call this migration AddPostClass. Run the Add-Migration AddPostClass command in Package Manager Console. Code First Migrations did a pretty good job of scaffolding these changes, but there are some things we might want to change: 1. First up, lets add a unique index to Posts.Title column (Adding in line 22 & 29 in the code below). 2. Were also adding a non-nullable Blogs.Rating column. If there is any existing data in the table it will get assigned the CLR default of the data type for new column (Rating is integer, so that would be 0). But we want to specify a default value of 3 so that existing rows in the Blogs table will start with a decent rating. (You can see the default value specified on line 24 of the code below)
http://msdn.microsoft.com/en-us/data/jj591621 7/12
24/4/2014
n a m e s p a c eM i g r a t i o n s D e m o . M i g r a t i o n s { u s i n gS y s t e m ; u s i n gS y s t e m . D a t a . E n t i t y . M i g r a t i o n s ; p u b l i cp a r t i a lc l a s sA d d P o s t C l a s s:D b M i g r a t i o n { p u b l i co v e r r i d ev o i dU p ( ) { C r e a t e T a b l e ( " d b o . P o s t s " , c= >n e w { P o s t I d=c . I n t ( n u l l a b l e :f a l s e ,i d e n t i t y :t r u e ) , T i t l e=c . S t r i n g ( m a x L e n g t h :2 0 0 ) , C o n t e n t=c . S t r i n g ( ) , B l o g I d=c . I n t ( n u l l a b l e :f a l s e ) , } ) . P r i m a r y K e y ( t= >t . P o s t I d ) . F o r e i g n K e y ( " d b o . B l o g s " ,t= >t . B l o g I d ,c a s c a d e D e l e t e :t r u e ) . I n d e x ( t= >t . B l o g I d ) . I n d e x ( p= >p . T i t l e ,u n i q u e :t r u e ) ; A d d C o l u m n ( " d b o . B l o g s " ," R a t i n g " ,c= >c . I n t ( n u l l a b l e :f a l s e ,d e f a u l t V a l u e :3 ) ) ; } p u b l i co v e r r i d ev o i dD o w n ( ) { D r o p I n d e x ( " d b o . P o s t s " ,n e w [ ]{" T i t l e "} ) ; D r o p I n d e x ( " d b o . P o s t s " ,n e w [ ]{" B l o g I d "} ) ; D r o p F o r e i g n K e y ( " d b o . P o s t s " ," B l o g I d " ," d b o . B l o g s " ) ; D r o p C o l u m n ( " d b o . B l o g s " ," R a t i n g " ) ; D r o p T a b l e ( " d b o . P o s t s " ) ; } } } Our edited migration is ready to go, so lets use Update-Database to bring the database up-to-date. This time lets specify the Verbose flag so that you can
http://msdn.microsoft.com/en-us/data/jj591621 8/12
24/4/2014
see the SQL that Code First Migrations is running. Run the Update-Database Verbose command in Package Manager Console.
p u b l i cs t r i n gA b s t r a c t{g e t ;s e t ;} We'll use the Add-Migration command to let Code First Migrations scaffold its best guess at the migration for us. Run the Add-Migration AddPostAbstract command in Package Manager Console. The generated migration takes care of the schema changes but we also want to pre-populate the Abstract column using the first 100 characters of content for each post. We can do this by dropping down to SQL and running an UPDATE statement after the column is added. (Adding in line 12 in the code below)
n a m e s p a c eM i g r a t i o n s D e m o . M i g r a t i o n s { u s i n gS y s t e m ; u s i n gS y s t e m . D a t a . E n t i t y . M i g r a t i o n s ; p u b l i cp a r t i a lc l a s sA d d P o s t A b s t r a c t:D b M i g r a t i o n { p u b l i co v e r r i d ev o i dU p ( ) { A d d C o l u m n ( " d b o . P o s t s " ," A b s t r a c t " ,c= >c . S t r i n g ( ) ) ; S q l ( " U P D A T Ed b o . P o s t sS E TA b s t r a c t=L E F T ( C o n t e n t ,1 0 0 )W H E R EA b s t r a c tI SN U L L " ) ; }
http://msdn.microsoft.com/en-us/data/jj591621 9/12
24/4/2014
p u b l i co v e r r i d ev o i dD o w n ( ) { D r o p C o l u m n ( " d b o . P o s t s " ," A b s t r a c t " ) ; } } } Our edited migration looks good, so lets use Update-Database to bring the database up-to-date. Well specify the Verbose flag so that we can see the SQL being run against the database. Run the Update-Database Verbose command in Package Manager Console.
24/4/2014
Run the Update-Database -Script -SourceMigration: $InitialDatabase -TargetMigration: AddPostAbstract command in Package Manager Console Code First Migrations will run the migration pipeline but instead of actually applying the changes it will write them out to a .sql file for you. Once the script is generated, it is opened for you in Visual Studio, ready for you to view or save.
u s i n gS y s t e m ; u s i n gS y s t e m . C o l l e c t i o n s . G e n e r i c ; u s i n gS y s t e m . L i n q ; u s i n gS y s t e m . T e x t ; u s i n gS y s t e m . D a t a . E n t i t y ; u s i n gM i g r a t i o n s D e m o . M i g r a t i o n s ; n a m e s p a c eM i g r a t i o n s D e m o { c l a s sP r o g r a m { s t a t i cv o i dM a i n ( s t r i n g [ ]a r g s ) { D a t a b a s e . S e t I n i t i a l i z e r ( n e wM i g r a t e D a t a b a s e T o L a t e s t V e r s i o n < B l o g C o n t e x t ,C o n f i g u r a t i o n > ( ) ) ;
http://msdn.microsoft.com/en-us/data/jj591621
11/12
24/4/2014
u s i n g( v a rd b=n e wB l o g C o n t e x t ( ) ) { d b . B l o g s . A d d ( n e wB l o g{N a m e=" A n o t h e rB l o g"} ) ; d b . S a v e C h a n g e s ( ) ; f o r e a c h( v a rb l o gi nd b . B l o g s ) { C o n s o l e . W r i t e L i n e ( b l o g . N a m e ) ; } } C o n s o l e . W r i t e L i n e ( " P r e s sa n yk e yt oe x i t . . . " ) ; C o n s o l e . R e a d K e y ( ) ; } } } Now whenever our application runs it will first check if the database it is targeting is up-to-date, and apply any pending migrations if it is not.
http://msdn.microsoft.com/en-us/data/jj591621
12/12