首页 > 代码库 > 微软ASP.NET网站部署指南(9):部署数据库更新

微软ASP.NET网站部署指南(9):部署数据库更新

1.  综述

无论什么时候,程序都有可能像代码更新一样更新数据库。本章节你将进行数据库改动,測试。然后部署到測试环境和生产环境。

提醒:假设依据本章节所做的操作出现错误信息或一些功能不正常的话,请务必check Troubleshooting页面

2.  给表加入新列

本小节,将改动StudentInstructor实体共同的基类Person类。加入一个birth date字段,也要在展示页面的表格上加入一个新列。

ContosoUniversity.DAL项目,打开Person.cs在类的末尾加入例如以下的代码属性(记得,大括号中面哦)。

[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[Required(ErrorMessage = "Birth date is required.")]
[Display(Name = "Birth Date")]
public DateTime? BirthDate { get; set; }

 

须要更新初始化类来支持新列,打开SchoolInitializer.cs文件找到var students = new List<Student>开头的代码,替换成包含birth date信息的例如以下的爱吗:

var students = new List<Student>
{
    new Student { FirstMidName = "Carson",   LastName = "Alexander", EnrollmentDate = DateTime.Parse("2005-09-01"), BirthDate = DateTime.Parse("1990-01-01") },
    new Student { FirstMidName = "Meredith", LastName = "Alonso",    EnrollmentDate = DateTime.Parse("2002-09-01"), BirthDate = DateTime.Parse("1989-01-15") },
    new Student { FirstMidName = "Arturo",   LastName = "Anand",     EnrollmentDate = DateTime.Parse("2003-09-01"), BirthDate = DateTime.Parse("1988-02-01") },
    new Student { FirstMidName = "Gytis",    LastName = "Barzdukas", EnrollmentDate = DateTime.Parse("2002-09-01"), BirthDate = DateTime.Parse("1987-03-15") },
    new Student { FirstMidName = "Yan",      LastName = "Li",        EnrollmentDate = DateTime.Parse("2002-09-01"), BirthDate = DateTime.Parse("1985-11-11") },
    new Student { FirstMidName = "Peggy",    LastName = "Justice",   EnrollmentDate = DateTime.Parse("2001-09-01"), BirthDate = DateTime.Parse("1970-11-21") },
    new Student { FirstMidName = "Laura",    LastName = "Norman",    EnrollmentDate = DateTime.Parse("2003-09-01"), BirthDate = DateTime.Parse("1992-10-11") },
    new Student { FirstMidName = "Nino",     LastName = "Olivetto",  EnrollmentDate = DateTime.Parse("2005-09-01"), BirthDate = DateTime.Parse("1986-06-06") }

};

 

var instructors = new List<Instructor>开头的代码块替换成例如以下代码:

var instructors = new List<Instructor>
{
    new Instructor { FirstMidName = "Kim",     LastName = "Abercrombie", HireDate = DateTime.Parse("1995-03-11"), BirthDate = DateTime.Parse("1918-08-12") },
    new Instructor { FirstMidName = "Fadi",    LastName = "Fakhouri",    HireDate = DateTime.Parse("2002-07-06"), BirthDate = DateTime.Parse("1960-03-15") },
    new Instructor { FirstMidName = "Roger",   LastName = "Harui",       HireDate = DateTime.Parse("1998-07-01"), BirthDate = DateTime.Parse("1970-01-11") },
    new Instructor { FirstMidName = "Candace", LastName = "Kapoor",      HireDate = DateTime.Parse("2001-01-15"), BirthDate = DateTime.Parse("1975-04-11") },
    new Instructor { FirstMidName = "Roger",   LastName = "Zheng",       HireDate = DateTime.Parse("2004-02-12"), BirthDate = DateTime.Parse("1957-10-12") }

};

 

在ContosoUniversity项目打开Instructors.aspx文件。加入一个模板字段来显示birth date,在hire date和office assignment字段之间:

<asp:TemplateField HeaderText="Birth Date" SortExpression="BirthDate">
    <ItemTemplate>
        <asp:Label ID="InstructorBirthDateLabel" runat="server" Text=‘<%# Eval("BirthDate", "{0:d}") %>‘></asp:Label>
    </ItemTemplate>
    <EditItemTemplate>
        <asp:TextBox ID="InstructorBirthDateTextBox" runat="server" Text=‘<%# Bind("BirthDate", "{0:d}") %>‘
            Width="7em"></asp:TextBox>
    </EditItemTemplate>
</asp:TemplateField>

(注:假设代码变形了,能够通过CTRL+K+D来格式化代码)

Students.aspx文件。在enrollment date 之前加入一个dynamic字段显示birth date:

<asp:DynamicField DataField="BirthDate" HeaderText="Birth Date" SortExpression="BirthDate"/>

 

StudentsAdd.aspx页面, enrollment date之前加入一个bound字段显示birth date:

<asp:BoundField DataField="BirthDate" HeaderText="Birth Date"
    SortExpression="BirthDate"/>

 

BLL\SchoolBL.cs文件, 支持按列排序的GetStudents 方法力的switch语句里的default语句之前。加入一个case分支以支持使用birth date排序:

case "BirthDate":
    students = students.OrderBy(s => s.BirthDate);
    break;
case "BirthDate DESC":
    students = students.OrderByDescending(s => s.BirthDate);
    break;

 

执行程序訪问Students页面,你可能感觉有一点慢,那是由于Entity Framework探測到了model变了,须要删除并重建数据库,然后将初始化里的数据插入到数据库。

页面载入以后,能够看到有了一个birth date新列。

 

技术分享

訪问Add StudentsInstructors页面验证是否有这个新列。

 

技术分享

 

技术分享

3.  部署数据库更新到測试环境

在生产环境。部署升级的时候须要保持曾经的数据,可是在測试环境则没有必要,只是为了使部署步骤和生产环境部署一样。我们还是在測试环境保存曾经的数据。以便部署步骤尽量一样。

对于生产环境。以下列出了一些须要follow的步骤:(忽略app_offline.htm步骤):

    从生产环境将School-Prod.sdf下载下来。放到Visual Studio项目的App_Data文件夹

    手工改变schema更新,手工更新数据

    又一次上传School-Prod.sdf到生产环境

    部署项目

(除了手工上传的方式,也能够使用和项目一起部署的方式,可是须要在项目属性里设置部署的时候将这个数据库也一起部署了(membership数据库除外),手工方式的优点是不用改动不论什么设置,依旧能够使用之前的one-click公布设置。

 

应用Schema改动

部署到冊数环境。你不必操心能否获得最新的copy,能够更新项目里下载下来的School-Prod.sdf来用。

看看Entity Framework里为School数据库做的改动,你能够手工改动測试环境和生产环境数据库。在Solution Explorer里双击App_Data\School.sdfServer Explorer里打开数据库连接。

Server Explorer里展开School-Dev.sdf,展开Tables-> Person->Columns。你能够看到Code First 生产的BirthDate列:

 

技术分享

Properties窗体,你能够看到BirthDate列的数据类型是datetime。 名称和数据类型是唯一须要改动的。

 

技术分享

Server Explorer里,右键School-Dev.sdf数据库然后选择关闭连接Close Connection

(这仅仅是数据库更新的简单样例,在真实环境里,数据库改动非常麻烦的。本章的重点不是改动或跟踪数据库变化,而是数据库改变怎么影响数据库部署过程。

普通的步骤就是:数据模型改变以后数据库须要怎么改变。以及Code First怎么自己主动更新数据库的,然后再用手工方式去做。)

下一步是手工改动School-Prod.sdf文件

Server Explorer里,展开School-Prod.sdf->Tables->Person->Columns。然后你能够看到老的表结构(没有BirthDate列)。

右键Person选择Edit Table Schema显示Edit Table对话框。

 

技术分享

在Edit Table对话框,在Discriminator以下加入一个新列,输入例如以下信息:

    Column Name: BirthDate     Data Type: datetime           

 

技术分享

 

技术分享

LengthAllow NullsUniquePrimary Key的默认值都没问题。点击OK

数据库和新代码可以非常好的一起执行了,可是BirthDate 列在測试数据库(后面的生产环境数据库)的位置和在Entity Framework Code First 里的位置是不一样的,由于Visual Studio tool for SQL Server Compact 仅仅支持在最以下加入新列。事实上,说实话仅仅是顺序不一样而已,没有什么大的问题。

在数据库方面,Visual Studio tool for SQL Server Compact 可能还会有其它的一些限制不能和Code First.的自己主动生产功能一样,你能够通过例如以下的方式来改进:

  • 使用WebMatrix的数据库操作功能,比Visual Studio 下的SQL Server Compact 的工具功能多。

  • 使用第三方或者开源工具,比如CodePlex 上的SQL Server Compact Toolbox 和 SQL Compact data and schema script utility
  • 自己写DDL(数据定义语言)脚本来维护数据库结构。
  • 迁移至SQL Server Express或完整版SQL Server以后。但是使用SQL Server Management Studio,使用完整的数据库维护功能,也能够使用Visual Studio 2010 SQL Server database projects 或者 Database Publishing Wizard 来自己主动生产脚本(可能还有其他的原因迁移至SQL Server,请看第2章节里的叙述)。

  • 使用Entity Framework Code First Migrations。自己主动更新新的数据库以匹配新的数据模型。本章节撰写之前。该工具还没用Release,只是但是使用NuGet来安装预览器。请參看Entity Framework team blog

 

更新数据

測试数据库的结果和新代码吻合了,可是你须要加入instructor 们的生日进去。你能够手工创建并执行一个SQL脚本。本章节已经帮你创建了这个脚本,你能够执行它。

Server Explorer里, 右键School-Prod.sdf库的Person表。选择New Query

 

技术分享

假设出现Add Table对话框的话,关闭它,然后将以下的SQL脚本拷贝到查询窗体的SQL窗格里:

UPDATE  Person SET   BirthDate = 1918-08-12 WHERE PersonID = 9;
UPDATE  Person SET   BirthDate = 1960-03-15 WHERE PersonID = 10;
UPDATE  Person SET   BirthDate = 1970-01-11 WHERE PersonID = 11;
UPDATE  Person SET   BirthDate = 1975-04-11 WHERE PersonID = 12;
UPDATE  Person SET   BirthDate = 1957-10-12 WHERE PersonID = 13;

技术分享

右键SQL窗格,选择Execute SQL。

 

技术分享

假设出现Query Definitions Differ对话框。点击Continue继续。

该消息仅仅是告诉你查询代码不能直观里表示在SQL窗格上面UI及时显示界面上。

 

技术分享

查询执行了,然后弹出了5条数据被更新的确认窗体。

 

技术分享

Server Explorer里,又一次右键Person选择Show Table Data检查instructors是否都有了生日数据。

 

技术分享

測试数据库如今能够部署了。

复制数据库到測试网站

在Windows Explorer资源管理器里,将ContosoUniversity项目的App_Data文件夹里的School-Prod.sdf文件拷贝到測试网站的App_Data文件夹(C:\inetpub\wwwroot\contosouniversity\App_Data),覆盖原来的数据库文件。

 

和数据库更新一起部署更新代码

能够部署更新的代码了, Solution Configurations下来菜单里选择Test。 Publish profile 里也选择Test。点击Publish Web。(假设因为自己定义了工具栏操作不了的话。參考:第8章节的内容)。

 

技术分享

Visual Studio部署了改动后的程序,并在Output窗体显示了成功信息。

 

技术分享

执行程序http://localhost/contosouniversity来验证更新是否成功部署,在Instructors 页面能够看到真实的birth date了。

 

技术分享

也能够执行Students页面 和Add Students页面来验证更新是否成功。

4.  部署数据库更新到生产环境

如今能够部署到生产环境了。除了须要先上传app_offline.htm文件防止用户使用网站以外。其他步骤和部署測试环境是一样的。

生产环境部署的过程例如以下:

  • 上传app_offline.htm文件到生产环境网站
  • 从生产环境网站下载School-Prod.sdf文件保存到本机的App_Data目录,然后再备份一份(见以下的凝视)。
  • 手工加入新列
  • 执行更新脚本(详细更新数据视真实环境须要而定)
  • 上传School-Prod.sdf文件到生产环境网站
  • 使用Visual Studio公布

凝视:数据库备份的话题就不多说了。肯定是须要常常备份的,这里指的是School-Prod.sdf 和aspnet-Prod.sdf文件。

最后一步和部署code-only 更新是一样的。在Solution Configurations下拉菜单里选择Release,在Publish profile下拉菜单里选择Production,然后点击Publish Web

 

技术分享

Visual Studio部署了改动后的程序。并在Output窗体显示了成功信息。

 

技术分享

验证是否正确部署之前。须要先删除app_offline.htm文件,删除以后。就能够执行网站来验证部署是否正常了。

 

技术分享

如今,你已经成功将包括数据库更新的应用程序部署到測试环境和生产环境了。

下一章节讲的是怎样将SQL Server Compact数据库迁移到SQL Server Express 或者完整版SQL Server上。

微软ASP.NET网站部署指南(9):部署数据库更新