ASP.NET MVC5--为数据库新增字段(涉及数据库迁移技术)

Setting up Code First Migrations for Model Changes--为模型更改做数据库迁移。

1.打开资源管理器,在App_Data文件夹下,找到movies.mdf数据库文件,如果没有看到点击显示所有文件。

2.删掉movies.mdf数据库文件,并编译项目。确保没有报错。

3.找到工具菜单栏下面的NuGet程序包管理器---程序包管理器控制台,如图所示:

4,在程序包管理器控制台中,输入:Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext

(注意: MvcMovie.Models.MovieDBContext    项目名.Models.项目数据上下文)

按enter键之后,可以看到:

5,数据库迁移之后,VS中自动为我们生成了一个Migrations文件夹,里面有一个Configuration.cs文件

6.打开Configuration.cs文件,引用命名空间:

using MvcMovie.Models;

然后在Seed方法中写上:

 1 protected override void Seed(MvcMovie.Models.MovieDBContext context)
 2 {
 3     context.Movies.AddOrUpdate( i => i.Title,
 4         new Movie
 5         {
 6             Title = "When Harry Met Sally",
 7             ReleaseDate = DateTime.Parse("1989-1-11"),
 8             Genre = "Romantic Comedy",
 9             Price = 7.99M
10         },
11
12          new Movie
13          {
14              Title = "Ghostbusters ",
15              ReleaseDate = DateTime.Parse("1984-3-13"),
16              Genre = "Comedy",
17              Price = 8.99M
18          },
19
20          new Movie
21          {
22              Title = "Ghostbusters 2",
23              ReleaseDate = DateTime.Parse("1986-2-23"),
24              Genre = "Comedy",
25              Price = 9.99M
26          },
27
28        new Movie
29        {
30            Title = "Rio Bravo",
31            ReleaseDate = DateTime.Parse("1959-4-15"),
32            Genre = "Western",
33            Price = 3.99M
34        }
35    );
36
37 }

7.Code First Migrations calls the Seed method after every migration (that is, calling update-database in the Package Manager Console), and this method updates rows that have already been inserted, or inserts them if they don‘t exist yet.

这句话的意思是:在每一次数据库迁移的时候,这个seed方法都会被调用,这个方法更新已经插入的行数据,或者插入行,如果这个行数据不存在。

8.下面的方法起到了一个更新插入的作用:

1 context.Movies.AddOrUpdate(i => i.Title,
2     new Movie
3     {
4         Title = "When Harry Met Sally",
5         ReleaseDate = DateTime.Parse("1989-1-11"),
6         Genre = "Romantic Comedy",
7         Rating = "PG",
8         Price = 7.99M
9     }

9.*因为Seed方法,在每次数据库迁移的时候,都会执行。你不能仅仅是插入数据,因为你将要插入的数据,将在第一次数据库迁移结束之后,已经存在数据库中;

*更新插入的操作可以预防错误,通过阻止你,插入已经存在的数据到数据库中。但是它有个缺点:它重载了,所有你在测试项目时候改变的数据;

因为有些测试数据,你不想改变:比如,你测试的时候,改变了数据,但是你不想这个数据在数据库更新的时候,发生改变。这个时候你可以做一个新增的操作:新增一个数据库中不存在的数据。

10.看一下这句代码吧:context.Movies.AddOrUpdate(i => i.Title,这第一个传到AddOrUpdate方法的参数,指定了一个属性,用来检查是否已经存在相同的行数据,对于我这个项目来说,我这个Title,可以做为这个属性,因为它在List中每次都是唯一的;This code assumes that titiles are unique. If you manually add a duplicate title, you‘ll get the following exception the next time you perform a migration.

     Sequence contains more than one element 我们假想Title是唯一的,如果你手动添加了重复的Title,你将会在下次数据库迁移的时候,报一个错误,了解更多,请参考链接的文章,哈哈,纯人工翻译的哦。因为博主喜欢英语,所以还是看外国人的资料学习编程了。MSDN很不错的,
For more information about the AddOrUpdate method, see Take care with EF 4.3 AddOrUpdate Method..

11.现在我们来编译一下整个项目吧,如果这这里不编译的话,后面的步骤中将会出错误。

12.The next step is to create a DbMigration class for the initial migration. This migration creates a new database, that‘s why you deleted the movie.mdf file in a previous step.
这句话的意思是:我们接下来要为初始化数据库迁移,创建一个DBMigration类,这个数据库迁移创建一个新的数据库,这也就是我们前面删掉Movie.mdf文件的原因。

13.在程序包管理器控制台中输入:

add-migration Initial

我们看到:

14.Code First Migrations creates another class file in the Migrations folder (with the name {DateStamp}_Initial.cs ), and this class contains code that creates the database schema. The migration filename is pre-fixed with a timestamp to help with ordering. Examine the {DateStamp}_Initial.cs file, it contains the instructions to create the Movies table for the Movie DB. When you update the database in the instructions below, this {DateStamp}_Initial.cs file will run and create the the DB schema. Then the Seed method will run to populate the DB with test data.

这段话的意思是:Code First迁移,在Migration文件下,创建了另外一个类(类的文件名称是:时间_Initiaal.cs),并且这个类包含了创建数据库的代码。这个文件以时间的命名方式便于排序管理。检查这个文件,它包含了怎么为MovieDB创建Moviess数据库表。当你按照下面的指令(等会我在控制器管理控制台中输入的指定),更新数据库的时候,这个文件会执行,并且创建数据库,然后这个Seed方法,也将会执行,为数据库生成测试数据。

先看看看这个文件里面的代码是啥样的吧:

 1 namespace MvcMovie.Migrations
 2 {
 3     using System;
 4     using System.Data.Entity.Migrations;
 5
 6     public partial class Initial : DbMigration
 7     {
 8         public override void Up()
 9         {
10             CreateTable(
11                 "dbo.Movies",
12                 c => new
13                     {
14                         ID = c.Int(nullable: false, identity: true),
15                         Title = c.String(),
16                         ReleaseDate = c.DateTime(nullable: false),
17                         Genre = c.String(),
18                         Price = c.Decimal(nullable: false, precision: 18, scale: 2),
19                     })
20                 .PrimaryKey(t => t.ID);
21
22         }
23
24         public override void Down()
25         {
26             DropTable("dbo.Movies");
27         }
28     }
29 }

同样看看我们之前的Migration里面Configuration.cs代码吧:

 1 namespace MvcMovie.Migrations
 2 {
 3     using MvcMovie.Models;
 4     using System;
 5     using System.Data.Entity;
 6     using System.Data.Entity.Migrations;
 7     using System.Linq;
 8
 9     internal sealed class Configuration : DbMigrationsConfiguration<MvcMovie.Models.MovieDBContext>
10     {
11         public Configuration()
12         {
13             AutomaticMigrationsEnabled = false;
14         }
15
16         protected override void Seed(MvcMovie.Models.MovieDBContext context)
17         {
18             context.Movies.AddOrUpdate(i => i.Title,
19         new Movie
20         {
21             Title = "When Harry Met Sally",
22             ReleaseDate = DateTime.Parse("1989-1-11"),
23             Genre = "Romantic Comedy",
24             Price = 7.99M
25         },
26
27          new Movie
28          {
29              Title = "Ghostbusters ",
30              ReleaseDate = DateTime.Parse("1984-3-13"),
31              Genre = "Comedy",
32              Price = 8.99M
33          },
34
35          new Movie
36          {
37              Title = "Ghostbusters 2",
38              ReleaseDate = DateTime.Parse("1986-2-23"),
39              Genre = "Comedy",
40              Price = 9.99M
41          },
42
43        new Movie
44        {
45            Title = "Rio Bravo",
46            ReleaseDate = DateTime.Parse("1959-4-15"),
47            Genre = "Western",
48            Price = 3.99M
49        }
50    );
51         }
52     }
53 }

现在我们在,程序包管理器控制台中输入这个指令来创建数据库,并运行seed方法:

update-database

我们可以看到:

If you get an error that indicates a table already exists and can‘t be created, it is probably because you ran the application after you deleted the database and before you executed update-database. In that case, delete theMovies.mdf file again and retry the update-database command. If you still get an error, delete the migrations folder and contents then start with the instructions at the top of this page (that is delete the Movies.mdf file then proceed to Enable-Migrations).

这句话的意思是:如果你运行上面的update-database指定,初始化数据表错误显示:数据表已经存在不能被创建,很可能是因为你在删除movie.mdf数据库文件之后,运行了项目,没有先执行updata-database指令。这种情况下,你可以再次删除movie.mdf文件,然后重新执行update-database命令。如果仍然报错,删除这个Migration文件夹和里面的内容,重新按照我这篇文章刚开始的步骤,做一遍。。。

15.运行项目:在地址栏中输入Movie。(我这里就不输入Movie了,因为我改了路由配置,默认是Movie控制器下面的Index方法)可以看到seed方法里面的数据,都显示出来了。

16.现在让我们开始今天真正的任务:给Model添加一个新字段

打开Models文件夹下面的Movie.cs文件,在里面加入如图所示的字段:

接着我们编译一下项目吧。

17.Because you‘ve added a new field to the Movie class, you also need to update the the binding white list so this new property will be included. Update the bind attribute for Create and Edit action methods to include the Ratingproperty:

这句话的意思是:因为你新增了一个字段到Movie类中,你同样需要去为Create方法和Edit方法更新绑定Bind:

[Bind(Include = "ID,Title,ReleaseDate,Genre,Price,Rating")]

18.You also need to update the view templates in order to display, create and edit the new Rating property in the browser view.

Open the \Views\Movies\Index.cshtml file and add a <th>Rating</th> column heading just after the Price column. Then add a <td> column near the end of the template to render the @item.Rating value. Below is what the updated Index.cshtml view template looks like:

你同样需要去更新视图模板为了在新增和编辑的时候,去显示你刚才添加的字段。  打开\Views\Movies\Index.cshtml文件,在Price字段后面,去新增一个<th>Rating</th>列标题,然后在这个视图模板的后面,写上要显示的数据 @item.Rating,具体看图片所示;

19.Next, open the \Views\Movies\Create.cshtml file and add the Rating field with the following highlighed markup. This renders a text box so that you can specify a rating when a new movie is created.

这句话的意思是:打开\Views\Movies\Create.cshtml 新增页面,添加Rating字段,使用下面的高亮显示的代码,这会生成一个文本框,所以在新增的时候,你可以指定一个Rating就可以添加到数据库中了。

如图:

现在已经完成了新增字段的功能任务了,我们来运行一下项目》》》

可以看到:

又报错了,数据库迁移方面的错误。。

20.You‘re seeing this error because the updated Movie model class in the application is now different than the schema of the Movie table of the existing database. (There‘s no Rating column in the database table.)

这句话的意思是:你看到这个错误,是因为你更新了模型中的Movie,它现在和已经存在的Movie表中的不一样,已经存在的Movie表中,是没有Rating字段的!!!

21.

There are a few approaches to resolving the error:

  1. Have the Entity Framework automatically drop and re-create the database based on the new model class schema. This approach is very convenient early in the development cycle when you are doing active development on a test database; it allows you to quickly evolve the model and database schema together. The downside, though, is that you lose existing data in the database — so you don‘t want to use this approach on a production database! Using an initializer to automatically seed a database with test data is often a productive way to develope an application. For more information on Entity Framework database initializers, see Tom Dykstra‘s fantastic ASP.NET MVC/Entity Framework tutorial.
  2. Explicitly modify the schema of the existing database so that it matches the model classes. The advantage of this approach is that you keep your data. You can make this change either manually or by creating a database change script.
  3. Use Code First Migrations to update the database schema.

这里有一些方法,来解决这个问题:

1.让EF基于新的实体类,自动的删除和再创建数据库。这个方法在开发项目的早期,是很方便实用的。但是这会让你丢失之前已经存在数据库中的数据,所以使用一个初始化器,来存储数据库中的测试数据是很好的一个解决方法。要了解更多,请看链接文章。

2.根据你的Model结构,修改数据库结构。这个方法的优点是你的数据不会丢失。你可以手动修改数据库,或者写数据库脚本来修改。

3.使用Code First Migration技术,来升级数据库。

这个教程,我们使用方法3,即Code First Migration技术来升级数据库。

22.Update the Seed method so that it provides a value for the new column. Open Migrations\Configuration.cs file and add a Rating field to each Movie object.

打开Configuration文件,在里面添加我们刚才新增的Rating字段到每一个Movie对象中。

 1 namespace MvcMovie.Migrations
 2 {
 3     using MvcMovie.Models;
 4     using System;
 5     using System.Data.Entity;
 6     using System.Data.Entity.Migrations;
 7     using System.Linq;
 8
 9     internal sealed class Configuration : DbMigrationsConfiguration<MvcMovie.Models.MovieDBContext>
10     {
11         public Configuration()
12         {
13             AutomaticMigrationsEnabled = false;
14         }
15
16         protected override void Seed(MvcMovie.Models.MovieDBContext context)
17         {
18             context.Movies.AddOrUpdate(i => i.Title,
19         new Movie
20         {
21             Title = "When Harry Met Sally",
22             ReleaseDate = DateTime.Parse("1989-1-11"),
23             Genre = "Romantic Comedy",
24             Price = 7.99M,
25             Rating="PG"
26         },
27
28          new Movie
29          {
30              Title = "Ghostbusters ",
31              ReleaseDate = DateTime.Parse("1984-3-13"),
32              Genre = "Comedy",
33              Price = 8.99M,
34              Rating = "PG"
35          },
36
37          new Movie
38          {
39              Title = "Ghostbusters 2",
40              ReleaseDate = DateTime.Parse("1986-2-23"),
41              Genre = "Comedy",
42              Price = 9.99M,
43              Rating = "PG"
44          },
45
46        new Movie
47        {
48            Title = "Rio Bravo",
49            ReleaseDate = DateTime.Parse("1959-4-15"),
50            Genre = "Western",
51            Price = 3.99M,
52            Rating = "PG"
53        }
54    );
55         }
56     }
57 }

Code First Migration

然后,我们编译一下项目。接着打开“程序包控制器管理台”,输入下面的指令:

add-migration Rating

23.The add-migration command tells the migration framework to examine the current movie model with the current movie DB schema and create the necessary code to migrate the DB to the new model. The name Rating is arbitrary and is used to name the migration file. It‘s helpful to use a meaningful name for the migration step.

When this command finishes, Visual Studio opens the class file that defines the new DbMIgration derived class, and in the Up method you can see the code that creates the new column.

这个add-migration Rating指令,告诉migration框架,用当前的MovieDB数据结构,去检查当前的movie model,为数据库迁移创建必要的代码。这个Rating字段用来写这个添加指令。使用有意义的名字,来进行这个步骤,是很有必要的。当这个指令完成后,VS打开这个类文件,并定义一个部分类,来继承DbMigration类。看代码就知道了:

24.我们再次运行项目吧,激动人心的时刻来了。。。错!!!我们应该先要执行这个:

Build the solution, and then enter the update-database command in the Package Manager Console window.(这一步坑死我了,我忘记执行了)。

新增字段运行新增的指令,之后,还得运行更新数据库的指令。就和db.SaveChanges()方法类似。这不执行完之后,才能是大功告成!!!

25.喜忧参半,之后,我们来运行项目吧。

可以看到:

这样就完成了数据库迁移技术的学习。欢迎大家评论,转载,我是@放飞梦想的翅膀,毕业于武汉软件工程职业学院。

时间: 2024-10-01 02:54:43

ASP.NET MVC5--为数据库新增字段(涉及数据库迁移技术)的相关文章

用ASP.NET MVC5 +SQLSERVER2014搭建多层架构的数据库管理系统

用http://ASP.NET MVC5 +SQLSERVER2014搭建多层架构的数据库管理系统 背景:前段时间,给一家公司做外包(就是图标是朵菊花那家).为了尽快实现交付,网上四处寻找适合中小型企业框架.花了几天无果,只在github上找了个(貌似作者还要收费),把前端半改造,后端彻底改造(最终版本全部没有使用github的代码).现在,把这段时间的成果最初版本贡献出来.若是有类似需求的同学,尽可拿去用,不清楚的可以留言. 本人认为:除非是定制的软件和定价了的软件可以收费外,开源的都应该免费

ASP.NET MVC5总结(三)登陆中常用技术解析之session与cookie

1.session机制 session机制是在服务器端保持状态的方案,在做系统登陆时,我们往往会用到session来存储一些用户登录的重要信息,而这些信息是不能存在cookie中的. 当访问量增多时,是会比较占用服务器性能的. 写session的方法 1 public static void WriteSession(string key, T value) 2 { 3 if (key.IsEmpty()) 4 return; 5 HttpContext.Current.Session[key]

ASP.NET MVC5利用EF,反向自动生成数据库

1.在Model类里面,写好相应的属性. 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Data.Entity; 6 7 namespace MvcMovie.Models 8 { 9 public class Movie 10 { 11 public int ID { get; set; } 12 public string

ASP.NET MVC5 网站开发实践(二) Member区域 - 添加文章

转自:http://www.cnblogs.com/mzwhj/p/3592895.html 上次把架构做好了,这次做添加文章.添加文章涉及附件的上传管理及富文本编辑器的使用,早添加文章时一并实现. 要点: 富文本编辑器采用KindEditor.功能很强大,国人开发,LGPL开源,自己人的好东西没有理由不支持. 附件的上传同样基于KindEditor实现,可以上传图片,flash,影音,文件等. 目录 ASP.NET MVC5 网站开发实践 - 概述 ASP.NET MVC5 网站开发实践(一)

学习ASP .NET MVC5官方教程总结(七)Edit方法和Edit视图详解

学习ASP .NET MVC5官方教程总结(七)Edit方法和Edit视图详解 在本章中,我们研究生成的Edit方法和视图.但在研究之前,我们先将 release date 弄得好看一点.打开Models\Movie.cs 文件.先添加一个引用: <span style="font-size:14px;">using System.ComponentModel.DataAnnotations;</span> 然后在Movie类中添加以下代码: [Display(

学习ASP .NET MVC5官方教程总结(六)通过控制器访问模型的数据

学习ASP .NET MVC5官方教程总结(六)通过控制器访问模型的数据 在本章中,我们将新建一个MoviesController 控制器,并编写获取电影数据的代码,使用视图模板将数据展示在浏览器中. 在进行下一步之前,你需要先编译应用程序,否则在添加控制器的时候会出错. 在解决方法资源管理器的Controllers文件夹右键,选择"添加">"新建搭建基架项": 在"添加支架"对话框,选择 包含视图的MVC 5控制器(使用 En),然后单击

关于数据库‘状态’字段设计的思考与实践

最近在做订单及支付相关的系统,在订单表的设计阶段,团队成员就‘订单状态’数据库字段设计有了一些分歧,网上也有不少关于这方面的思考和探讨,结合这些资料和项目的实际情况,拟对一些共性问题进行更深一层的思考,笔耕在此,和大家一起探讨. 问题综述 这里的分歧点即有团队内部的分歧点,也有网络上常见的一些分歧点,先将存在的分歧点抛出来: 1.订单表的‘订单状态’字段对应的字典值应当包含哪些状态值?对于‘已评论’.‘已退货’.’已退款’这类状态是放到‘订单状态’中?还是独立一个字段标识? 2.订单表的‘订单状

ASP.NET MVC5(二):控制器、视图与模型

前言 本篇博文主要介绍ASP.NET MVC中的三个核心元素:控制器.视图与模型,以下思维导图描述了本文的主要内容. 控制器 控制器简介 在介绍控制器之前,简单的介绍一下MVC工作原理:URL告知路由机制该使用哪个控制器(Controller),调用该控制器中的哪个方法(Action),并为该方法提供需要的参数.控制器响应用户的输入,在响应时修改模型(Model),并决定使用哪个视图(View),并对该视图进行渲染.注意:MVC模式提供的是方法调用结果,而不是动态生成的页面. 以上内容对于初学者

ASP.NET MVC5(一):ASP.NET MVC概览

ASP.NET MVC概览 ASP.NET MVC是一种构建Web应用程序的框架,它将一般的MVC(Model-View-Controller)模式应用于ASP.NET框架. ASP.NET MVC模式简介 MVC将Web应用程序划分为三个主要的部分,以下是MSDN给出的定义: 模型(Model):模型对象是实现应用程序数据域逻辑的应用程序部件. 通常,模型对象会检索模型状态并将其存储在数据库中. 例如,Product 对象可能会从数据库中检索信息,操作该信息,然后将更新的信息写回到 SQL S