【EF6学习笔记】(五)数据库迁移及部署
原文地址:Code First Migrations and Deployment
原文主要讲两部分:开发环境下数据库迁移到其他数据库服务器;以及在Azure上如何部署应用;
迁移数据库
原文前面讲一堆内容,主要就是说数据库在开发过程中,如果数据模型经常需要调整,那么数据库每次都删除重建有点不太现实;尤其是对于已部署的正式环境,需要的仅仅是数据库升级,而不可能直接Drop掉,再重新Create.
所以,需要启用EF的数据迁移功能。
原文为了演示效果更好,就直接演示了迁移升级到一个全新的数据库中:
第1步:把Web.config文件中 entityFramework节点下 contexts注释掉:
<entityFramework>
<!--<contexts>
<context type="EFTest.DAL.SchoolContext, EFTest">
<databaseInitializer type="EFTest.DAL.SchoolInitializer, EFTest" />
</context>
</contexts>-->
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
第2步:数据库连接字符串中,数据库名改个名字,比如EFTest2
<connectionStrings>
<add name="SchoolContext" connectionString="Data Source=(localdb)\ProjectsV13;Initial Catalog=EFTest2;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;" providerName="System.Data.SqlClient" />
</connectionStrings>
第3步:打开PM控制台:
第4步: 先执行 enable-migrations , 会创建一个Migrations子目录,并多出一个Configuration.cs文件;
再执行 add-migration InitialCreate , 会在Migrations子目录创建一个带时间戳的 xxxxxxxxxx_InitialCreate文件;
第5步,在Configuration.cs文件 有个Seed方法就是用来初始化数据库的时候放入的种子数据; 可以如以下方式加入数据:
在这个要注意,Seed方法在后面执行update-database
命令的时候会被执行,而且每次执行update-database
命令的时候都会执行;
所以这个地方需要用AddOrUpdate来处理一些种子数据,防止插入重复数据;
另外,注意一些外键数据,例如是数据库自增长的列,则需要前面先保存的数据到数据库,然后才用ID这属性值(不然ID是没数据的)
namespace EFTest.Migrations
{
using Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq; internal sealed class Configuration : DbMigrationsConfiguration<EFTest.DAL.SchoolContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
} protected override void Seed(EFTest.DAL.SchoolContext context)
{
// This method will be called after migrating to the latest version. // 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" }
// );
// var students = new List<Student>
{
new Student { FirstMidName = "Carson", LastName = "Alexander",
EnrollmentDate = DateTime.Parse("2010-09-01") },
new Student { FirstMidName = "Meredith", LastName = "Alonso",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Arturo", LastName = "Anand",
EnrollmentDate = DateTime.Parse("2013-09-01") },
new Student { FirstMidName = "Gytis", LastName = "Barzdukas",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Yan", LastName = "Li",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Peggy", LastName = "Justice",
EnrollmentDate = DateTime.Parse("2011-09-01") },
new Student { FirstMidName = "Laura", LastName = "Norman",
EnrollmentDate = DateTime.Parse("2013-09-01") },
new Student { FirstMidName = "Nino", LastName = "Olivetto",
EnrollmentDate = DateTime.Parse("2005-08-11") }
};
students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s));
context.SaveChanges(); var courses = new List<Course>
{
new Course {CourseID = , Title = "Chemistry", Credits = , },
new Course {CourseID = , Title = "Microeconomics", Credits = , },
new Course {CourseID = , Title = "Macroeconomics", Credits = , },
new Course {CourseID = , Title = "Calculus", Credits = , },
new Course {CourseID = , Title = "Trigonometry", Credits = , },
new Course {CourseID = , Title = "Composition", Credits = , },
new Course {CourseID = , Title = "Literature", Credits = , }
};
courses.ForEach(s => context.Courses.AddOrUpdate(p => p.Title, s));
context.SaveChanges(); var enrollments = new List<Enrollment>
{
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alexander").ID,
CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID,
Grade = Grade.A
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alexander").ID,
CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID,
Grade = Grade.C
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alexander").ID,
CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alonso").ID,
CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alonso").ID,
CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alonso").ID,
CourseID = courses.Single(c => c.Title == "Composition" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Anand").ID,
CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Anand").ID,
CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Barzdukas").ID,
CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Li").ID,
CourseID = courses.Single(c => c.Title == "Composition").CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Justice").ID,
CourseID = courses.Single(c => c.Title == "Literature").CourseID,
Grade = Grade.B
}
}; foreach (Enrollment e in enrollments)
{
var enrollmentInDataBase = context.Enrollments.Where(
s =>
s.Student.ID == e.StudentID &&
s.Course.CourseID == e.CourseID).SingleOrDefault();
if (enrollmentInDataBase == null)
{
context.Enrollments.Add(e);
}
}
context.SaveChanges();
}
}
}
带时间戳的 xxxxxxxxxx_InitialCreate文件本次不需要自己调整,主要包含了Up和Down 方法;
Up用来升级数据库;Down用来恢复数据库;
第6步:在PM控制台输入 update-database
进行数据升级(本次是新建一个新数据库EFTest2 并新建表,并插入种子数据)
部署至 Azure
后面部分原文采用的是国际版的Azure,并且是经典管理页面,后面本人将采用国内世纪互联版Azure以及新的资源组管理页面来测试部署应用;
前提条件:需要有世纪互联运营的中国区Azure订阅账号!
www.portal.azure.cn 用订阅账号登录。
步骤1:先新建一个资源组用来进行综合管理项目下属的Azure资源(如 App Service , SQL DB, 或者以后Blob 存储等)
步骤2:建SQL Server 数据库,本次先用SQL Server 测试;(Azure也支持MySQL)
先输入数据库名称,选择第1步创建好的资源组;点击配置Server,在右页点击新建一个Server (如果已经有DB Server ,可以直接选择,一个Server上可以多个DB实例)
如果是新建的Server ,需要输入Server Name ,以及设置访问的账号及密码;选择区域,人在上海,所以选择东区;
默认的数据库规格有点高,测试就用最小的规格就可以。。。选择Price Tier 改为 5DTU 2GB
点击Create后,等创建结束即可;可以点击刷新按钮看下:
步骤3:数据库新建后,就可以做次数据库迁移;
在做数据库迁移之前,需要设置Azure的数据库可以被本地的IP地址访问到:
点击选中SQL 数据库,在Overview的右页点击 Set Server firewall
不需要自己去查自己的外网IP地址是多少,已经自动帮你列好,只要点上面的Add client IP按钮即可:
千万记得点 Save
获取连接字符串:
把拷贝的数据库连接字符串粘贴到应用的Web.Config
(请把账号和密码填进去。。。。。不要忘记了)
然后直接在PMC输入 update-database
步骤4:新建App Service
选择Web App:
一堆废话就不看了,点创建按钮:
输入AppName,选择资源组,点击App Service plan/Location 按钮,在右页点击Create New:
输入App Service Plan Name ,选择区域,点击Prcing tier ,选择B1 Basic (最便宜,测试嘛,能省则省)
选好后,点创建按钮:
一般几分钟后,就能创建成功;
步骤5: 设置VS2017可以访问中国版Azure :
参考:
https://docs.azure.cn/zh-cn/articles/others/aog-portal-management-qa-vs2017-login
步骤6:发布应用
VS2017登录成功后,可以在Server Explorer里看到自己的Azure订阅,以及订阅下面的所有资源;
邮件点击项目发布后,选择发布到MS Azure App Service , 并点选Select Existing ,然后点Publish按钮:
选择准备发布的App Serivce ,然后点 Ok按钮:
Output窗口输出结果:
成功后,会自动启动浏览器打开网页:
【EF6学习笔记】(五)数据库迁移及部署的更多相关文章
- Flask学习笔记:数据库迁移操作flask-script+alembic/flask-migrate
数据库迁移是将代码中模型类(即表)的修改同步到数据库中, flask-sqlalchemy的模型类一旦使用create_all()映射到数据库中后,对这个模型类的修改(例如添加了一个新的字段)就不会再 ...
- EF6 学习笔记(五):数据库迁移及部署
EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 原文地址:Code First Migrations and Deployment 原文主要讲两部分:开发环境下 ...
- EF6 学习笔记(一):Code First 方式生成数据库及初始化数据库实际操作
EF6 学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 本篇参考原文地址: Creating an Entity Framework Data Model 说明:学习 ...
- 【EF6学习笔记】目录
[EF6学习笔记](一)Code First 方式生成数据库及初始化数据库实际操作 [EF6学习笔记](二)操练 CRUD 增删改查 [EF6学习笔记](三)排序.过滤查询及分页 [EF6学习笔记]( ...
- ASP.NET MVC5 及 EF6 学习笔记 - (目录整理)
个人从传统的CS应用开发(WPF)开始转向BS架构应用开发: 先是采用了最容易上手也是最容易搞不清楚状况的WebForm方式入手:到后面就直接抛弃了服务器控件的开发方式,转而采用 普通页面+Ajax+ ...
- EF6学习笔记(六) 创建复杂的数据模型
EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 本篇原文地址:Creating a More Complex Data Model 本篇讲的比较碎,很多内容本人 ...
- EF6学习笔记(四) 弹性连接及命令拦截调试
EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 本章原文地址:Connection Resiliency and Command Interception 原文 ...
- EF6 学习笔记(二):操练 CRUD 增删改查
EF6学习笔记总目录 ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 接上篇: EF6 学习笔记(一):Code First 方式生成数据库及初始化数据库实际操作 本篇原文链接: I ...
- Kettle学习笔记(一)— 环境部署及运行
目录 Kettle学习笔记(一)-环境部署及运行 Kettle学习笔记(二)- 基本操作 kettle学习笔记(三)- 定时任务的脚本执行 Kettle学习笔记(四)- 总结 Kettle简介 Ket ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
随机推荐
- py3.0第五天,常用模块
本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configpars ...
- ie9 不执行js,打开控制台就好了
IE仅在开启developer tools的时候,脚本才能访问到console这个对象 (console在代码调试时很有帮助,但是在生产环境中,应该移除掉,或至少应该先判断这个对象是否存在,毕竟无插件 ...
- MongoDB的数据备份与恢复
一:数据备份操作 步骤: 1.以管理员身份打开cmd,然后打开到mongdb的bin文件夹 2.输入命令 mongodump -h dbhost -d dbname -o dbdirectory -h ...
- Maven学习笔记1(clean compile package install)
Maven是一个项目构建管理工具,使用相应的命令 就可以快速完成项目的编译 打包. 1.下载maven,直接解压目录就可以了,配置maven的环境变量就可以在window下的任何文件夹下以命令的方式执 ...
- scrapy的入门使用(一)
1. scrapy项目实现流程 创建一个scrapy项目:scrapy startproject mySpider 生成一个爬虫:scrapy genspider 提取数据:完善spider,使用x ...
- Flask web 开发出现错误:TypeError: Allowed methods have to be iterables of strings, for example: @app.route(..., methods=["POST"])
没有发现普通都语法错误,然后一一比对官方教程里面的代码,发现是在“@bp.route('/<int:id>/delete', methods=('POST'))”这一行代码里面method ...
- 熟悉常用的Linux操作
请按要求上机实践如下linux基本命令. cd命令:切换目录 (1)切换到目录 /usr/local cd /usr/local (2)去到目前的上层目录 cd .. (3)回到自己的主文件夹 ...
- 卷积神经网络中的channel 和filter
在深度学习的算法学习中,都会提到 channels 这个概念.在一般的深度学习框架的 conv2d 中,如 tensorflow .mxnet,channels 都是必填的一个参数. channels ...
- 背水一战 Windows 10 (122) - 其它: 通过 Windows.System.Profile 命名空间下的类获取信息, 查找指定类或接口的所在程序集的所有子类和子接口
[源码下载] 背水一战 Windows 10 (122) - 其它: 通过 Windows.System.Profile 命名空间下的类获取信息, 查找指定类或接口的所在程序集的所有子类和子接口 作者 ...
- TIME_WAIT状态过多的排查
一.概述 (一)现象 服务器有两个现象,第一是tcp连接数不多,不超过10个,但是time_wait状态的2000.第二个按照以往的性质,在很少用户访问的情况下,服务器的资源几乎没有使用,比如CPU, ...