参考:
本文内容:
1,学习Entity Framework Code First 迁移功能(Migrations)
2,更新Model Class(Model Class中添加新的字段),然后把更新应用于datebase.
默认情况下,就像我们之前用Models
下的movie.cs
右键点击直接添加database
的时候,Code First
自动在数据库中添加新的表来记录新添加的database
时候和movie.cs
同步,如果不同步,Entity Framework
就会跑出错误。这样我们就可以在开发的过程中发现错误,而不是必须在运行的时候才发现错误。
一,为Model的改变设置Code First Migrations功能(Setting up Code First Migrations for Model Changes),从而可以让movie.cs改变的时候,把改变应用于Database(Model类和自动生成的数据库同步)
1,1删除MovieDBContext,删除.mdf文件
1.2Ctrl+Shift+B重建解决方案后,打开“套件管理器控制台”:
PM>提示符后面执行Enable-Migrations命令开启Code First Migrations功能,我们现在直接输入:Enable-Migrations,可以看到提示命令:
我们需要Enable的是Movie,直接Copy提示命令中的下面的一行命令:
Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext
开启成功:
解决方案下创建了Migrations文件夹:
1.3,更改Configuration.cs中的写Seed方法,打开Configuration.cs,我们看到 protected override void Seed(MVCMovie.Models.MovieDBContext context) { //这个方法将会在Migrations后被调用 // This method will be called after migrating to the latest version. //你可以用DbSet<T>的.AddOrUpdate扩展方法,避免创建重复的数据 // You can use the DbSet<T>.AddOrUpdate() helper extension method // to avoid creating duplicate seed data. E.g. // // context.People.AddOrUpdate( // p => p.FullName, // new Person { FullName = "Andrew Peters" }, // new Person { FullName = "Brice Lambson" }, // new Person { FullName = "Rowan Miller" } // ); // } View Code 更新Seed方法:
protected override void Seed(MvcMovie.Models.MovieDBContext context){ context.Movies.AddOrUpdate( i => i.Title, new Movie { Title = "When Harry Met Sally", ReleaseDate = DateTime.Parse("1989-1-11"), Genre = "Romantic Comedy", Price = 7.99M }, new Movie { Title = "Ghostbusters ", ReleaseDate = DateTime.Parse("1984-3-13"), Genre = "Comedy", Price = 8.99M }, new Movie { Title = "Ghostbusters 2", ReleaseDate = DateTime.Parse("1986-2-23"), Genre = "Comedy", Price = 9.99M }, new Movie { Title = "Rio Bravo", ReleaseDate = DateTime.Parse("1959-4-15"), Genre = "Western", Price = 3.99M } ); } View Code
添加引用:
Code First Migrations 在每一次migration之后都会调用这个Seed方法,从而更新Database中的数据(Insert orUpdate)
1,4重建解决方案。为Migrations创建一个新的DbMigration
.cs
类继承自DbMigration
,这一步将会新建一个Database,这就是我们之前要删除movie.mdf
的原因.在Package Manager Console
中执行命令:add-migration Initial
生成 intial migration. “intial”
是任意命名的,用来命名创建的migration
文件。这个类是用来创建新的数据库 Code First
创建了一个带有时间戳的_Initial.cs
,这个类中的代码实现了创建数据库表,当你更新类中的表的时候,_Initial.cs
将会运行更新dabatbase
中的表,然后Seed
方法填充测试数据到Database
的Table
中。这些迁移文件类文件都是以时间戳为前缀命名并排序的: public partial class Initial : DbMigration
{
public override void Up()
{
CreateTable(
" dbo.Movies ",
c =>
new {
ID = c.Int(nullable:
false, identity:
true),
Title = c.String(),
ReleaseDate = c.DateTime(nullable:
false),
Genre = c.String(),
Price = c.Decimal(nullable:
false, precision:
18, scale:
2),
})
.PrimaryKey(t => t.ID);
}
public override void Down()
{
DropTable(
" dbo.Movies ");
}
}
View Code 现在我们运行命令PM>update-datebase 来创建数据库,运行Seed方法:
如果运行update-database方法的时提示Table已经存在,是因为你在删除表之后运行了项目。如果是这样再次把Movie.mdf删除,然后执行update-datebase命令。如果还是报错,删除Migrations文件夹,然后从上面删除Movie.mdf处重新按照本文介绍的一步一步来。
Ctrl+F5执行程式,我们看到了Seed方法中的数据:
二,在Movie Model中添加新的属性字段,把字段同步到DB的Table中
namespace MVCMovie.Models{ //Moive 类就相当于数据库中的一张名为Movie的Table //Movie 类实例化的对象相当于Table中的一行,实例的各个属性(ID,Title...)相当于Table中的列 public class Movie { public int ID { get; set; } public string Title { get; set; } public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } public string Rating { get; set; } } //MovieDBContext class ,继承自Entity Framework中的DbContext,代表这Movie数据上下文 //MovieDBContext class ,读取、存储、更新Movie Class 实例 public class MovieDBContext : DbContext { public DbSet<Movie> Movies { get; set; } }} View Code Ctrl+Shift+B重建解决方案,然后在View中的各个页面添加Rating属性:
<div
class=
" editor-label ">
@Html.LabelFor(model => model.Rating)
</div>
<div
class=
" editor-field ">
@Html.EditorFor(model => model.Rating)
@Html.ValidationMessageFor(model => model.Rating)
</div>
View Code Ctrl+F5运行程序,提示如下:
这是因为我们刚刚在Model中的Movie.cs中添加了新的属性字段,Movie.cs中的字段和已经存在的Database中的表字段不一致:
我们用Code First Migrations
来解决这个问题:1,
在Seed
中的每一个对象实例中添加 Rating= "G",如:
context.Movies.AddOrUpdate(i => i.Title,
new Movie
{
Title =
" When Harry Met Sally ",
ReleaseDate = DateTime.Parse(
" 1989-1-11 "),
Genre =
" Romantic Comedy ",
Rating =
" G ",
Price =
7.99M },
View Code
2,
执行以下命令PM>add-migration AddRatingMig
这个命令告诉migration framework 检查当前的movie model是否和dabatase 中的Movie 字段一致,如果不一致,就会添加必要的code来更新DB和新的Model一致:
3,解决方案下面新建了带有时间戳的_AddRatingMig.cs文件,文件中有添加和删除新的列,保证Model和DB
中的字段一致
namespace MVCMovie.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class AddRatingMig : DbMigration
{
public override void Up()
{
AddColumn(
" dbo.Movies ",
" Rating ", c => c.String());
}
public override void Down()
{
DropColumn(
" dbo.Movies ",
" Rating ");
}
}
}
View Code
4,执行命令PM>update-database
5,刷新”MovieDBContext”后我们看到在Movie.cs中添加的属性同步到了DB的Table中:
Migrations Configuration.cs中的Sample数据也填充到了Database中:
6,Ctrl+Shift+B
,Ctrl+F5
运行,我们看到所有的页面中都有了Rating:
这一节,我们可以在Model中添加新的属性,并且同步到DB中。我们也学习了,把Sample数据填充到DB的Table中。下一节,我们将会在Model Class中对新增数据添加逻辑验证(validation logic)和业务规则(business rules).
See You。。。