Asp.net MVC 中Code First 迁移使用
如果模型类(数据库上下文类Context和POCO类)发生改变,与数据库中的结构不一致,系统默认会抛出一个异常。可以考虑使用代码优先迁移。
代码优先迁移执行UpSert数据库操作,它在每一次更新数据库(Update-Database)后执行,添加数据库中没有的记录,更新数据库已有的记录,通过UI添加的记录保持不变。(模型更改后需要重新编译程序,并修改各视图和方法绑定的白名单,如果不是第一次迁移,还需要设置迁移文件交下configtion.cs文件中的seed方法增加或改变字段。)执行步骤如下:
1、启用迁移。在库程序包控制台输入Enable-Migrations,(如果多个上下文对象,需要指定完整的上下文类,包括所在的命名空间如Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext),自动创建一个Migration 迁移文件夹,并在下面创建一个Configurations.cs的文件。可以在里面设置种子方法。
protected override void Seed(MvcMovie.Models.MovieDBContext context)
{
List<Movie> movies =new List<Movie>
{
new Movie{ Title="封神榜",ReleaseDate=DateTime.Parse("2015-1-10"),Genre="神话",Price=50.6M,Rating="成人" },
new Movie{ Title="喜羊羊与灰太狼",ReleaseDate=DateTime.Parse("2008-5-1"),Genre="卡通",Price=30.2M,Rating="儿童" },
new Movie{ Title="何以笙箫默",ReleaseDate=DateTime.Parse("2014-11-5"),Genre="爱情",Price=102.5M,Rating="成人" },
new Movie{ Title="倚天屠龙记",ReleaseDate=DateTime.Parse("2010-7-1"),Genre="武侠",Price=70.05M,Rating="成人" },
new Movie{ Title="天龙八部",ReleaseDate=DateTime.Parse("1998-8-8"),Genre="武侠",Price=200.2M,Rating="成人" },
new Movie{ Title="全面回忆",ReleaseDate=DateTime.Parse("2012-6-10"),Genre="科幻",Price=80.3M,Rating="成人" },
new Movie{ Title="黑衣人",ReleaseDate=DateTime.Parse("2014-6-12"),Genre="科幻",Price=150.3M,Rating="成人" },
new Movie{ Title="熊出没",ReleaseDate=DateTime.Parse("2013-8-13"),Genre="卡通",Price=40.6M,Rating="儿童" },
new Movie{ Title="西游记",ReleaseDate=DateTime.Parse("1984-5-21"),Genre="神话",Price=110.05M,Rating="成人" },
};
movies.ForEach(m => context.Movies.AddOrUpdate(s => s.Title, m));
//或者 context.Movies.AddOrUpdate(m => m.Title, movies.ToArray());
context.SaveChanges();
}
2、创建迁移。在库程序包控制台输入 Add-Migration Rating。程序将比对模型类(数据库上下文类Context和POCO类)与数据库的一致性,将创建一个时间戳+迁移名字的cs文件,里面包含有根据模型类创建更改数据库的UP方法。可以在执行UpDate-Database 前创建多个迁移,然后它们能按照顺序依次执行,是因为在每个迁移文件前有一个时间戳。
同时
3、升级数据库。编译程序,在库程序包控制台输入 Update-Database 。第一个任务是将运行当前的迁移文件中的代码对数据库更改UP方法,第二是报告迁移配置文件中的Seed方法upsert数据,通过UI更改的数据如与Seed方法中的数据不一致,将还原成种子方法的数据。通过UI新增的数据能保存。
4、如果没有对模型作任何更改,运行update-database,就不会执行迁移,但会再次运行Seed方法,如果在UI界面中修改了Seed方法中的记录,数据库中的记录将还原成种子方法的记录值。
二、如果一个项目中有多个上下文类,在创建迁移的时候需要指定详细的上下文类或者指定可选的迁移文件夹目录,以防冲突。如果一个项目中有多个迁移,增加迁移和升级数据库时同样需要指定详细的迁移配置文件。
比如:1、一个项目中有多个上下文类,启用迁移
Enable-Migrations -ContextTypeName SimpleSite.Models.ApplicationDbContext -MigrationsDirectory Migrations\Identity
2、增加迁移:Add-Migration CssTheme -ConfigurationTypeName SimpleSite.Migrations.Identity.Configuration
3、升级数据库:Update-Database -ConfigurationTypeName SimpleSite.Migrations.Identity.Configuration 示例:
启用迁移: Enable-Migrations -ContextTypeName MajorConstruction.Models.MajorContext 如果不指定-MigrationsDirectory 默认是迁移文件是在项目的Migrations 文件夹下面。
增加迁移:Add-Migration ArticleIsShow -ConfigurationTypeName MajorConstruction.Migrations.Configuration
升级数据库:Update-Database -ConfigurationTypeName MajorConstruction.Migrations.Configuration
如果迁移是增加或修改必填写字段,如Boolean值。则可以修改有时间戳的迁移文件中指定默认值,因为执行升级数据库命令后,先是运行迁移文件中的UP方法,再运行Configuration配置文件下的 Seed种子方法。
如:
public partial class ArticleIsShow : DbMigration
{
public override void Up()
{
AddColumn("dbo.Article", "ArticleIsShow", c => c.Boolean(nullable: false,defaultValue:true));
}
public override void Down()
{
DropColumn("dbo.Article", "ArticleIsShow");
}
}
}
三、可以在数据库上下文类中,为数据库上下文中指定连接字符串,多个上下文可以指定同一个连接字符串(但他们拥有不同的Dbset,也就是不同的实体集也就是对应的表),这样,就可以访问同一个数据库。同时,还可以在配置文件中,修改约定。
public class SiteDataContext:DbContext
{
public SiteDataContext() : base("DefaultConnection") { } //调用基类的构造函数。
public DbSet<Notification> Notifications { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
当对数据库中已有数据的情况下执行迁移,需要插入存根数据来满足表格的外键约束,比如有表格新增了一列不能为空的外键。可以在UP方法中建立一个临时的值记录作为默认的值满足外键约束,在up方法中,所有的记录都设置为这个默认值,然后种子方法会将有些记录设置成正确的值。
比如 原来的Course 实体没有DepartmentID 这个属性,而本次迁移执行前,数据库中已经有了记录了。
就需要在迁移文件中为DepartmentID 指定默认值.
// Create a department for course to point to.
Sql("INSERT INTO dbo.Department (Name, Budget, StartDate) VALUES ('Temp', 0.00, GETDATE())");
// default value for FK points to department created above.
AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false, defaultValue: 1));
//AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false));
对于多对多关系,EF Code First 会自动创建关联的 各主键约束表格,但可以通过Fluent API配置表格的列名和表名。
modelBuilder.Entity<Course>()
.HasMany(c => c.Instructors).WithMany(i => i.Courses)
.Map(t => t.MapLeftKey("CourseID")
.MapRightKey("InstructorID")
Asp.net MVC 中Code First 迁移使用的更多相关文章
- 学习ASP.NET MVC(九)——“Code First Migrations ”工具使用示例
在上一篇文章中,我们学习了如何使用实体框架的“Code First Migrations ”工具,使用其中的“迁移”功能对模型类进行一些修改,同时同步更新对应数据库的表结构. 在本文章中,我们将使用“ ...
- ASP.NET MVC中使用窗体验证出现上下文的模型在数据库创建后发生更改,导致调试失败(一)
在ASP.NET MVC中使用窗体验证.(首先要明白,验证逻辑是应该加在Model.View和Controller哪一个里面?由于Model的责任就是负责信息访问与商业逻辑验证的,所以我们把验证逻辑加 ...
- 如何在 ASP.NET MVC 中集成 AngularJS(3)
今天来为大家介绍如何在 ASP.NET MVC 中集成 AngularJS 的最后一部分内容. 调试路由表 - HTML 缓存清除 就在我以为示例应用程序完成之后,我意识到,我必须提供两个版本的路由表 ...
- 如何在 ASP.NET MVC 中集成 AngularJS(2)
在如何在 ASP.NET MVC 中集成 AngularJS(1)中,我们介绍了 ASP.NET MVC 捆绑和压缩.应用程序版本自动刷新和工程构建等内容. 下面介绍如何在 ASP.NET MVC 中 ...
- asp.net mvc 中 一种简单的 URL 重写
asp.net mvc 中 一种简单的 URL 重写 Intro 在项目中想增加一个公告的功能,但是又不想直接用默认带的那种路由,感觉好low逼,想弄成那种伪静态化的路由 (别问我为什么不直接静态化, ...
- Entity Framework在Asp.net MVC中的实现One Context Per Request(附源码)
上篇中"Entity Framework中的Identity map和Unit of Work模式", 由于EF中的Identity map和Unit of Work模式,EF体现 ...
- 为Asp.net MVC中的RenderSection设置默认内容
1. RenderSection的简单介绍 Asp.net MVC中提供了RenderSection方法,这样就能够在Layout中定义一些区块,这些区块留给使用Layout的view来实现比如我们定 ...
- IoC容器Autofac - Autofac + Asp.net MVC + EF Code First(转载)
转载地址:http://www.cnblogs.com/JustRun1983/archive/2013/03/28/2981645.html 有修改 Autofac通过Controller默认构造 ...
- ASP.NET MVC中使用ASP.NET AJAX异步访问WebService
使用过ASP.NET AJAX的朋友都知道,怎么通过ASP.NET AJAX在客户端访问WebService,其实在ASP.NET MVC中使用ASP.NET AJAX异步访问WebService 也 ...
随机推荐
- bzoj3875 【Ahoi2014】骑士游戏 spfa处理后效性动规
骑士游戏 [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,JYY一共有两种攻 ...
- 使用Sencha Architect开发Sencha Touch应用的整理
官网:http://www.sencha.com/ 其实官网上的文档都很清楚了,不过整理一下总比较好 第一步,软件准备 注: 以下软件的安装本着这样两条原则 一是不要安装在中文目录下 二是不要安装在带 ...
- 【HDOJ6343】Graph Theory Homework(贪心)
题意: 给定n个点,每个点有权值a[i],从A走到B的花费是下取整sqrt(a[i]-a[j]),求从1号点走到n号点的最小花费 1<=n,a[i]<=1e5 思路: #include&l ...
- Python基础教程笔记——第7章:更加抽象(类)
下面进入Python的面向对象: 对象的魔力: 多态:---可以对不同类的对象使用同样的操作 封装:---对外部隐藏对象内部的工作方式 继承:---以普通的类为基础建立专门的类对象 (1)多态: is ...
- Android资源目录结构
资源目录结构 res为资源目录,主要以xml语法编写静态的资源. 资源的命名标准:小写字母和数字,且以小写字母开头. 资源的生成,为了和java语法沟通,资源文件会自动的生成在[gen]目录的R.ja ...
- java数据结构和算法09(哈希表)
树的结构说得差不多了,现在我们来说说一种数据结构叫做哈希表(hash table),哈希表有是干什么用的呢?我们知道树的操作的时间复杂度通常为O(logN),那有没有更快的数据结构?当然有,那就是哈希 ...
- win10 powershell 验证下载的包的MD5/sha1的签名值
巧用Win10自带的PowerShell命令校验文件的Hash值(MD5.SHA1/256等) 发表于2017年3月8日由MS酋长 通常为了保证我们从网上下载的文件的完整性和可靠性,我们把文件下载下来 ...
- 判断所ping主机的操作系统
根据它的值判断所ping主机的操作系统类型. TTL被称为生存期,也就是你所传输的数据在网络上经过的路由器的最大个数. 操作系统 TTLLINUX 64WIN2K/NT 128WINDOWS 系列 3 ...
- Android TextView设置个别字体样式
TextView进一步深化: Textview 能够对其文字进行格式化. 通过查询资料,了解到格式化文字的方式主要分为两大类: 第一类:HTML标签格式化文字 代码 ...
- MySQL基础笔记(五) 视图
一.什么是视图 视图是一个虚拟表.也就是说,视图在外观和行为上都类似于表,但它不需要实际的物理存储,只保存了视图定义(查询语句). 视图由select查询所定义 -- 当创建一个视图时,实际上是在数据 ...