使用 Visual Studio ASP.NET Web 部署:部署数据库更新

作者 :Tom Dykstra

下载初学者项目

本教程系列介绍如何使用 Visual Studio 2012 或 Visual Studio 2010 将 (发布) ASP.NET Web 应用程序部署到Azure 应用服务 Web 应用或第三方托管提供程序。 有关该系列的信息,请参阅 系列中的第一个教程

概述

在本教程中,你将进行数据库更改和相关代码更改,在 Visual Studio 中测试更改,然后将更新部署到测试、过渡和生产环境。

本教程首先介绍如何更新由 Code First 迁移 管理的数据库,然后介绍如何使用 dbDacFx 提供程序更新数据库。

提醒:如果在完成本教程时收到错误消息或某些内容不起作用,请确保检查故障排除页面

使用 Code First 迁移 部署数据库更新

在本部分中,将向 和 Instructor 实体的Person基类Student添加出生日期列。 然后,更新显示讲师数据的页面,使其显示新列。 最后,将更改部署到测试、暂存和生产。

向应用程序数据库中的表添加列

  1. ContosoUniversity.DAL 项目中,打开 Person.cs 并在类的 Person 末尾添加以下属性, () 后应有两个右大括号:

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

    接下来,更新 Seed 方法,使其为新列提供值。 打开 Migrations\Configuration.cs 并替换以下代码块(包括出生日期信息)开头 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"), OfficeAssignment = new OfficeAssignment { Location = "Smith 17" } },
        new Instructor { FirstMidName = "Fadi",    LastName = "Fakhouri",    HireDate = DateTime.Parse("2002-07-06"), BirthDate = DateTime.Parse("1960-03-15"), OfficeAssignment = new OfficeAssignment { Location = "Gowan 27" } },
        new Instructor { FirstMidName = "Roger",   LastName = "Harui",       HireDate = DateTime.Parse("1998-07-01"), BirthDate = DateTime.Parse("1970-01-11"), OfficeAssignment = new OfficeAssignment { Location = "Thompson 304" } },
        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") }
    };
    
  2. 生成解决方案,然后打开 “包管理器控制台” 窗口。 请确保仍选择 ContosoUniversity.DAL 作为 默认项目

  3. “包管理器控制台”窗口中,选择“ContosoUniversity.DAL”作为“默认”项目,然后输入以下命令:

    add-migration AddBirthDate
    

    此命令完成后,Visual Studio 将打开定义新 DbMigration 类的类文件,在 方法中 Up 可以看到创建新列的代码。 方法 Up 在实现更改时创建列,在回滚更改时, Down 方法会删除该列。

    AddBirthDate_migration_code

  4. 生成解决方案,然后在 “包管理器控制台” 窗口中输入以下命令, (确保仍) 选择 ContosoUniversity.DAL 项目:

    update-database
    

    实体框架运行 方法, Up 然后运行 Seed 方法。

在“讲师”页中显示新列

  1. 在 ContosoUniversity 项目中,打开 Instructors.aspx 并添加新的模板字段以显示出生日期。 在雇用日期和办公室分配之间添加它:

    <asp:TemplateField HeaderText="Hire Date" SortExpression="HireDate">
        <ItemTemplate>
            <asp:Label ID="InstructorHireDateLabel" runat="server" Text='<%# Eval("HireDate", "{0:d}") %>'></asp:Label>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:TextBox ID="InstructorHireDateTextBox" runat="server" Text='<%# Bind("HireDate", "{0:d}") %>' Width="7em"></asp:TextBox>
        </EditItemTemplate>
    </asp:TemplateField>
    <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>
    <asp:TemplateField HeaderText="Office Assignment" SortExpression="OfficeAssignment.Location">
        <ItemTemplate>
            <asp:Label ID="InstructorOfficeLabel" runat="server" Text='<%# Eval("OfficeAssignment.Location") %>'></asp:Label>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:TextBox ID="InstructorOfficeTextBox" runat="server"
                Text='<%# Eval("OfficeAssignment.Location") %>' Width="7em"
                OnInit="InstructorOfficeTextBox_Init"></asp:TextBox>
        </EditItemTemplate>
    </asp:TemplateField>
    

    (如果代码缩进不同步,可以按 Ctrl-K,然后按 CTRL-D 自动重新格式化文件。)

  2. 运行应用程序并单击“ 讲师” 链接。

    加载页面时,会看到它具有新的出生日期字段。

    “讲师”页面的屏幕截图,其中显示了他们的姓名、雇用日期、出生日期和办公室分配。

  3. 关闭浏览器。

部署数据库更新

  1. 解决方案资源管理器选择 ContosoUniversity 项目。

  2. “Web 一键发布 ”工具栏中,单击“ 测试 发布”配置文件,然后单击“ 发布 Web”。 (如果工具栏处于禁用状态,请在 解决方案资源管理器.) 中选择 ContosoUniversity 项目

    Visual Studio 部署更新的应用程序,浏览器将打开主页。

  3. 运行“ 讲师 ”页,验证是否已成功部署更新。

    当应用程序尝试访问此页的数据库时,Code First 会更新数据库架构并运行 Seed 方法。 显示页面时,会看到包含日期的预期 “出生日期” 列。

  4. “Web 一键发布 ”工具栏中,单击 “暂存 发布”配置文件,然后单击“ 发布 Web”。

  5. 在暂存中运行 “讲师 ”页,验证是否已成功部署更新。

  6. “Web 一键发布 ”工具栏中,单击 “生产 发布”配置文件,然后单击“ 发布 Web”。

  7. 在生产环境中运行 “讲师 ”页,验证是否已成功部署更新。

    对于包含数据库更改的实际生产应用程序更新,通常还会使用 app_offline.htm在部署期间使应用程序脱机,如上一教程所示。

使用 dbDacFx 提供程序部署数据库更新

在本部分中,将向成员资格数据库中的“用户”表添加一个“注释”列,并创建一个页面,用于显示和编辑每个用户的批注。 然后,将更改部署到测试、暂存和生产。

向成员资格数据库中的表添加列

  1. 在 Visual Studio 中,打开SQL Server 对象资源管理器

  2. 展开 (localdb) \v11.0,展开 “数据库”,展开 aspnet-ContosoUniversity (而不是 aspnet-ContosoUniversity-Prod) ,然后展开 “表”。

    如果在SQL Server节点下没有看到 (localdb) \v11.0,请右键单击SQL Server节点,然后单击“添加SQL Server”。 在“ 连接到服务器 ”对话框中,输入 (localdb) \v11.0 作为 服务器名称,然后单击“ 连接”。

    如果看不到 aspnet-ContosoUniversity,请运行项目,使用管理员凭据登录, (密码是 devpwd) ,然后刷新SQL Server 对象资源管理器窗口。

  3. 右键单击“用户”表,然后单击“查看Designer”。

    SSOX 视图Designer

  4. 在设计器中,添加“ 注释” 列并将其设置为 nvarchar (128) 和可以为 null,然后单击“ 更新”。

    “添加注释”列

  5. “预览数据库汇报”框中,单击“更新数据库”。

    预览数据库汇报

创建用于显示和编辑新列的页面

  1. “解决方案资源管理器”中,右键单击 ContosoUniversity 项目中的“帐户”文件夹,单击“添加”,然后单击“新建项”。

  2. 使用母版页创建新的 Web 窗体并将其命名为 UserInfo.aspx。 接受默认 的 Site.Master 文件作为母版页。

  3. 将以下标记复制到元素中 MainContentContent , (3 Content 个元素) 中的最后一个:

    <h2>User Information</h2>
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:DefaultConnection %>" 
            SelectCommand="SELECT UserId, UserName, Comments FROM [Users]" 
            UpdateCommand="UPDATE [Users] SET [UserName] = @UserName, [Comments] = @Comments WHERE [UserId] = @UserId">
            <DeleteParameters>
                <asp:Parameter Name="UserId" Type="Object" />
            </DeleteParameters>
            <UpdateParameters>
                <asp:Parameter Name="UserId" Type="Object" />
                <asp:Parameter Name="UserName" Type="String" />
                <asp:Parameter Name="Comments" Type="String" />
            </UpdateParameters>
        </asp:SqlDataSource>
    
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="UserId" DataSourceID="SqlDataSource1">
            <Columns>
                <asp:CommandField ShowEditButton="True" />
                <asp:BoundField DataField="UserName" HeaderText="UserName" SortExpression="UserName" />
                <asp:BoundField DataField="Comments" HeaderText="Comments" SortExpression="Comments" />
            </Columns>
        </asp:GridView>
    
  4. 右键单击 “UserInfo.aspx ”页,然后单击“ 在浏览器中查看”。

  5. 使用 管理员 用户凭据登录, (密码是 devpwd) ,并向用户添加一些注释,以验证页面是否正常工作。

    显示 UserInfo 页的屏幕截图,其中显示了 UserName 测试和 Comment Tom 的测试帐户。

  6. 关闭浏览器。

部署数据库更新

若要使用 dbDacFx 提供程序进行部署,只需在发布配置文件中选择 “更新数据库 ”选项。 但是,在使用此选项时,对于初始部署,还配置了一些要运行的其他 SQL 脚本:这些脚本仍在配置文件中,必须阻止它们再次运行。

  1. 右键单击 ContosoUniversity 项目并单击“发布”,打开“发布Web”向导。

  2. 选择 “测试 配置文件”。

  3. 单击“设置”选项卡。

  4. “默认连接”下,选择“ 更新数据库”。

  5. 禁用配置为为初始部署运行的其他脚本:

    1. 单击“ 配置数据库更新”。
    2. “配置数据库汇报”对话框中,清除 Grant.sqlaspnet-data-dev.sql 旁边的检查框。
    3. 单击“关闭”。
  6. 单击 预览 选项卡。

  7. “数据库” 下,单击 “DefaultConnection”右侧的 “预览数据库 ”链接。

    数据库预览版

    预览窗口显示将在目标数据库中运行的脚本,使该数据库架构与源数据库的架构匹配。 该脚本包含一个 ALTER TABLE 命令,用于添加新列。

  8. 关闭“ 数据库预览 ”对话框,然后单击“ 发布”。

    Visual Studio 部署更新的应用程序,浏览器将打开主页。

  9. 运行 UserInfo 页 (将 Account/UserInfo.aspx 添加到主页 URL) ,以验证是否已成功部署更新。 必须通过输入 admindevpwd 登录。

    默认情况下,表中的数据不会部署,并且未配置要运行的数据部署脚本,因此找不到在开发中添加的注释。 现在可以在暂存中添加新注释,以验证更改是否已部署到数据库以及页面是否正常工作。

  10. 按照相同的过程部署到过渡和生产环境。

    不要忘记禁用额外的脚本。 与测试配置文件相比,唯一的区别在于,在过渡和生产配置文件中仅禁用一个脚本,因为它们配置为仅运行 aspnet-prod-data.sql

    过渡和生产的凭据是管理员凭据和 prodpwd。

    对于包含数据库更改的实际生产应用程序更新,通常还会在部署期间将应用程序脱机,方法是在发布之前上传 app_offline.htm ,然后删除应用程序,如 上一教程所示。

总结

现在,你已使用 Code First 迁移 和 dbDacFx 提供程序部署了包含数据库更改的应用程序更新。

显示“讲师”页面的屏幕截图,其中显示其姓名、雇用日期、出生日期和 Office 分配。

UserInfo 页面的屏幕截图,其中显示了 UserName 测试和 Comment Tom 的测试帐户。

下一教程介绍如何使用命令行执行部署。