{"id":1074,"date":"2013-11-01T12:36:05","date_gmt":"2013-11-01T12:36:05","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/webdev\/2013\/11\/01\/tips-when-making-changes-in-entity-framework-code-first-models-after-scaffolding\/"},"modified":"2022-08-09T03:19:38","modified_gmt":"2022-08-09T10:19:38","slug":"tips-when-making-changes-in-entity-framework-code-first-models-after-scaffolding","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/tips-when-making-changes-in-entity-framework-code-first-models-after-scaffolding\/","title":{"rendered":"Tips When Making Changes in Entity Framework Code First Models after Scaffolding"},"content":{"rendered":"<p>When you scaffold an existing Entity Framework model, using MVC5 scaffolding in Visual Studio 2013, you can easily run into the issue of \u201c<em>The model backing the &lt;DbContextName&gt; context has changed since the database was created<\/em>\u201d as shown below. <\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/11\/2605.image_thumb_6C0012A7.png\"><img decoding=\"async\" title=\"image\" border=\"0\" alt=\"image\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/11\/2605.image_thumb_6C0012A7.png\" width=\"644\" height=\"82\" \/><\/a><\/p>\n<p>For example, in an MVC project, add the following model.<\/p>\n<pre class=\"csharpcode\">    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> Product\r\n    {\r\n        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">int <\/span>Id { get; set; }\r\n        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Name { get; set; }\r\n    }<\/pre>\n<p>Scaffold the Product model using \u201cMVC 5 Controller with views, using Entity Framework\u201d scaffolder in Visual Studio 2013. View the generated pages, Index\/Edit\/Details\/Create, to verify things are working properly.<\/p>\n<p>Now, suppose we need to modify the Product model to add more fields, like Description and Category.<\/p>\n<pre class=\"csharpcode\">    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> Product\r\n    {\r\n        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">int<\/span> Id { get; set; }\r\n        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Name { get; set; }\r\n        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Description { get; set; }\r\n        <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Category { get; set; }\r\n    }<\/pre>\n<p>Scaffold the Product model again and view a scaffold page, you will see the error message mentioned above. The exception is caused by the model change, not actually a scaffolding issue. However, because of the order in which users do things, it might sometimes appear to be related to scaffolding.<\/p>\n<p>There are a few ways to workaround this error; each has some pros and cons, depending on what you need.<\/p>\n<h4>1) Code First Migration with Entity Framework.<\/h4>\n<p>Following the instructions at <a href=\"http:\/\/msdn.microsoft.com\/en-us\/data\/jj591621\" target=\"_blank\" rel=\"noopener\">Code First Migration<\/a> requires a number of steps. <\/p>\n<p>First, you need to bring up \u201cPackage Manager Console\u201d, Tools \u2013&gt; Library Package Manger \u2013&gt; Package Manager Console, and run the <strong>Enable-Migrations<\/strong> command in the console as the first step to enable migrations for your context. <\/p>\n<div id=\"codeSnippetWrapper\">\n<div id=\"codeSnippet\">\n<pre>PM&gt; Enable-Migrations -ContextTypeName WebApplication7.Models.WebApplication7Context<\/pre>\n<p><!--CRLF--><\/p>\n<pre>Checking <span>if<\/span> the context targets an existing database...<\/pre>\n<p><!--CRLF--><\/p>\n<pre>Detected database created with a database initializer. Scaffolded migration <span>'201309271941079_InitialCreate'<\/span> corresponding to existing database. To use an automatic migration instead, delete the Migrations folder and re-run Enable-Migrations specifying the -EnableAutomaticMigrations parameter.<\/pre>\n<p><!--CRLF--><\/p>\n<pre>Code First Migrations enabled <span>for<\/span> project WebApplication7.<\/pre>\n<p><!--CRLF--><\/div>\n<\/div>\n<p>&#160;<\/p>\n<p>From now on, each time you modify the model and re-run the scaffolding, you need to run the <strong>Add-Migration<\/strong>, and <strong>Update-Database<\/strong> commands. In our example above, after adding Description and Category, we run those commands as follows.<\/p>\n<div id=\"codeSnippetWrapper\">\n<div id=\"codeSnippet\">\n<pre>PM&gt; Add-Migration AddDescriptionCategory<\/pre>\n<p><!--CRLF--><\/p>\n<pre>Scaffolding migration <span>'AddDescriptionCategory'<\/span>.<\/pre>\n<p><!--CRLF--><\/p>\n<pre>The Designer Code <span>for<\/span> <span>this<\/span> migration file includes a snapshot of your current Code First model. This snapshot <span>is<\/span> 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 <span>in<\/span> <span>this<\/span> migration, then you can re-scaffold it by running <span>'Add-Migration AddDescriptionCategory'<\/span> again.<\/pre>\n<p><!--CRLF--><\/p>\n<pre>PM&gt; Update-Database<\/pre>\n<p><!--CRLF--><\/p>\n<pre>Specify the <span>'-Verbose'<\/span> flag to view the SQL statements being applied to the target database.<\/pre>\n<p><!--CRLF--><\/p>\n<pre>Applying <span>explicit<\/span> migrations: [201309280107120_AddDescriptionCategory].<\/pre>\n<p><!--CRLF--><\/p>\n<pre>Applying <span>explicit<\/span> migration: 201309280107120_AddDescriptionCategory.<\/pre>\n<p><!--CRLF--><\/p>\n<pre>Running Seed method.<\/pre>\n<p><!--CRLF--><\/p>\n<pre>PM&gt; <\/pre>\n<p><!--CRLF--><\/div>\n<\/div>\n<p>Now you can test view the scaffolded pages and won\u2019t see the error anymore.<\/p>\n<p>The good thing about this approach is you just modify the exact table representing the model that you\u2019re changing, and leave the rest of the database intact. However, if you do a lot of changes on the model and want some quick verification of the scaffold pages, going through those steps each time can add a considerable amount of time. Also, those steps will add a number of files into your projects that can grow quickly.<\/p>\n<p>Migration is usually the best choice when you use it to deploy to production the initial time and when you\u2019re deploying updates to production later. For more information about migrations for deployment, see <a href=\"http:\/\/www.asp.net\/web-forms\/tutorials\/deployment\/visual-studio-web-deployment\/introduction\">http:\/\/www.asp.net\/web-forms\/tutorials\/deployment\/visual-studio-web-deployment\/introduction<\/a>. <\/p>\n<p>For rapid development, option 2 and 3 below might be a better choice.<\/p>\n<h4>2) Modify the Database name in the connectionString<\/h4>\n<p>A quick workaround to the existing database issue without going through all the database migration steps would be to modify the connection string in web.config. Each time you change the code first model and scaffold it, you can give the connection string a new \u201cInitial Catalog\u201d and \u201cAttachDbFilename\u201d value. <\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/11\/0574.image_thumb_59B74BE5.png\"><img decoding=\"async\" title=\"image\" border=\"0\" alt=\"image\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2013\/11\/0574.image_thumb_59B74BE5.png\" width=\"644\" height=\"152\" \/><\/a><\/p>\n<p> This approach will create a new database each time you give a new database name in the connection string and leave the old database unused. This might not be ideal if you already have a large existing database. However, it could be useful if you just want to verify something quick once or twice.<\/p>\n<p>&#160;<\/p>\n<h4>3) Database Initializer with Entity Framework<\/h4>\n<p>With the second workaround, you still need to remember to modify the connection string each time the model is changed. If you want to make one setting, and forget about it when you\u2019re building your app, you can achieve this with a custom initializer class. EF will drop, recreate and re-seed the database each time the model changes, and you set up this action only once in your project. <\/p>\n<p>Following is an example of a custom initializer class.<\/p>\n<div id=\"codeSnippetWrapper\">\n<div id=\"codeSnippet\">\n<pre><span>public<\/span> <span>class<\/span> SchoolInitializer : DropCreateDatabaseIfModelChanges&lt;SchoolContext&gt;<\/pre>\n<p><!--CRLF--><\/p>\n<pre>    {<\/pre>\n<p><!--CRLF--><\/p>\n<pre>        <span>protected<\/span> <span>override<\/span> <span>void<\/span> Seed(WebApplication3Context context)<\/pre>\n<p><!--CRLF--><\/p>\n<pre>        {<\/pre>\n<p><!--CRLF--><\/p>\n<pre>            var students = <span>new<\/span> List&lt;Student&gt;<\/pre>\n<p><!--CRLF--><\/p>\n<pre>            {<\/pre>\n<p><!--CRLF--><\/p>\n<pre>                <span>new<\/span> Student { FirstMidName = <span>&quot;Carson&quot;<\/span>,   LastName = <span>&quot;Alexander&quot;<\/span>, EnrollmentDate = DateTime.Parse(<span>&quot;2005-09-01&quot;<\/span>) },<\/pre>\n<p><!--CRLF--><\/p>\n<pre>                <span>new<\/span> Student { FirstMidName = <span>&quot;Meredith&quot;<\/span>, LastName = <span>&quot;Alonso&quot;<\/span>,    EnrollmentDate = DateTime.Parse(<span>&quot;2002-09-01&quot;<\/span>) },<\/pre>\n<p><!--CRLF--><\/p>\n<pre>                <span>new<\/span> Student { FirstMidName = <span>&quot;Arturo&quot;<\/span>,   LastName = <span>&quot;Anand&quot;<\/span>,     EnrollmentDate = DateTime.Parse(<span>&quot;2003-09-01&quot;<\/span>) },<\/pre>\n<p><!--CRLF--><\/p>\n<pre>                <span>new<\/span> Student { FirstMidName = <span>&quot;Gytis&quot;<\/span>,    LastName = <span>&quot;Barzdukas&quot;<\/span>, EnrollmentDate = DateTime.Parse(<span>&quot;2002-09-01&quot;<\/span>) },<\/pre>\n<p><!--CRLF--><\/p>\n<pre>                <span>new<\/span> Student { FirstMidName = <span>&quot;Yan&quot;<\/span>,      LastName = <span>&quot;Li&quot;<\/span>,        EnrollmentDate = DateTime.Parse(<span>&quot;2002-09-01&quot;<\/span>) },<\/pre>\n<p><!--CRLF--><\/p>\n<pre>                <span>new<\/span> Student { FirstMidName = <span>&quot;Peggy&quot;<\/span>,    LastName = <span>&quot;Justice&quot;<\/span>,   EnrollmentDate = DateTime.Parse(<span>&quot;2001-09-01&quot;<\/span>) },<\/pre>\n<p><!--CRLF--><\/p>\n<pre>                <span>new<\/span> Student { FirstMidName = <span>&quot;Laura&quot;<\/span>,    LastName = <span>&quot;Norman&quot;<\/span>,    EnrollmentDate = DateTime.Parse(<span>&quot;2003-09-01&quot;<\/span>) },<\/pre>\n<p><!--CRLF--><\/p>\n<pre>                <span>new<\/span> Student { FirstMidName = <span>&quot;Nino&quot;<\/span>,     LastName = <span>&quot;Olivetto&quot;<\/span>,  EnrollmentDate = DateTime.Parse(<span>&quot;2005-09-01&quot;<\/span>) }<\/pre>\n<p><!--CRLF--><\/p>\n<pre>            };<\/pre>\n<p><!--CRLF--><\/p>\n<pre>            students.ForEach(s =&gt; context.Students.Add(s));<\/pre>\n<p><!--CRLF--><\/p>\n<pre>            context.SaveChanges();<\/pre>\n<p><!--CRLF--><\/p>\n<pre>        }<\/pre>\n<p><!--CRLF--><\/p>\n<pre>    }<\/pre>\n<p><!--CRLF--><\/div>\n<\/div>\n<p>Then add the following code in Global.asax.cs<\/p>\n<pre class=\"csharpcode\">    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> MvcApplication : System.Web.HttpApplication\r\n    {\r\n        <span class=\"kwrd\">protected<\/span> <span class=\"kwrd\">void<\/span> Application_Start()\r\n        {\r\n          Database.SetInitializer&lt;<font color=\"#2ba6d5\">SchoolContext<\/font>&gt;(new <span class=\"kwrd\"><font color=\"#2ba6d5\">SchoolInitializer<\/font>()<\/span>);\r\n        }\r\n    }<\/pre>\n<p>From now on, you can just focus on building the right model for your application, scaffold, and test it as many times as you need, and don\u2019t have to do anything extra in order to avoid the error mentioned at the beginning of this blog. <\/p>\n<p>This approach will drop and create a new database only when the model is changed, and it won\u2019t leave behind a lot of unused databases, which option 2 will do. <\/p>\n<p>Another way to tell Entity Framework to use your initializer class is to add an element to the <em>entityFramework<\/em> element in the application\u2019s Web.config file, instead of modifying the Global.asax.cs file. For more information about how to do it, you can read Tom&#8217;s fabulous blog at <a href=\"http:\/\/www.asp.net\/mvc\/tutorials\/getting-started-with-ef-using-mvc\/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application\" target=\"_blank\" rel=\"noopener\">Creating an Entity Framework Data Model for an ASP.NET MVC Application<\/a>. Setting up the initializer in the Web.Config file is sometimes preferable because you can turn it on or off or change it without changing code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you scaffold an existing Entity Framework model, using MVC5 scaffolding in Visual Studio 2013, you can easily run into the issue of \u201cThe model backing the &lt;DbContextName&gt; context has changed since the database was created\u201d as shown below. For example, in an MVC project, add the following model. public class Product { public int [&hellip;]<\/p>\n","protected":false},"author":423,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197],"tags":[],"class_list":["post-1074","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet"],"acf":[],"blog_post_summary":"<p>When you scaffold an existing Entity Framework model, using MVC5 scaffolding in Visual Studio 2013, you can easily run into the issue of \u201cThe model backing the &lt;DbContextName&gt; context has changed since the database was created\u201d as shown below. For example, in an MVC project, add the following model. public class Product { public int [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/1074","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/423"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=1074"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/1074\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=1074"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=1074"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=1074"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}