使用 MVC4 和 MVC Scaffold 的 Code First 和 Entity Framework 5






4.78/5 (32投票s)
使用 MVC4 和 MVC Scaffold 的 Code First 和 Entity Framework 5
引言
本文将带您完成一个使用 MVC4 和 Entity Framework 5 的简单应用程序,并演示如何利用 Code First 技术。我将使用 MvsScaffold 快速创建控制器和视图。我们将创建一个待办事项应用程序。
必备组件
- Visual Studio 2010 SP1
- MVC 4
- Visual Studio 的 Nuget 包管理器
- SqlExpress 数据库
背景
- Code First – Code First 使您能够通过 C# 或 Visual Basic .NET 类来描述模型。Code First 是自 Entity Framework 4.1 起可用的一种新的开发方法。您可以使用 Code First 从模型生成新数据库,或将您的模型映射到现有数据库。您可以 在此处 阅读更多内容。
- Entity Framework - Entity Framework (EF) 是一个对象关系映射器,它使 .NET 开发人员能够使用领域特定的对象来处理关系数据。它消除了开发人员通常需要编写的大部分数据访问代码。您可以 在此处 了解更多信息。
- MVC 4 – 作为 MVC3 的继任者,ASP.NET MVC 4 是一个用于构建可伸缩的、基于标准的 Web 应用程序的框架,它使用成熟的设计模式以及 ASP.NET 和 .NET Framework 的强大功能。您可以在 此处 找到所有相关信息。
- MVC Scaffolding – 这是一个 ASP.NET 的 Scaffolding 包,通过 NuGet 使用 ‘Install-Package MvcScaffolding’ 命令进行安装。感谢 Scott Hanselman 和 Steven Anderson。
快速准备
在我们开始之前,请确保您已经安装了 NuGet 包管理器和 SQL 组件(如果您还没有的话)。
在 Visual Studio 2010(我使用的是 Professional 版本)中,转到 工具 –> 扩展管理器…
点击 ‘在线库’,在搜索框中输入 NuGet 并按回车键。它将显示 NuGet 包管理器。我已经安装了它,您可以看到绿色的勾号。如果您尚未安装,请双击它进行安装,然后按照说明进行操作。
安装 NuGet 包后,您应该能够看到库包管理器。工具->库包管理器->程序包管理器控制台
点击此菜单项应该会打开 powershell 控制台
输入 Install-Package EntityFramework.SqlServerCompact,然后按 Enter。这将安装 SQL 组件。
步骤说明
步骤 1: 创建新的 MVC 4 应用程序
创建一个新的 MVC4 应用程序,我们称之为 TODO步骤 2:选择 Internet Application 模板,并将 Razor 作为视图引擎
选择 Internet Application,并将视图引擎选择为 Razor
步骤 3:安装 MvcScaffolding
打开程序包管理器控制台(工具->库包管理器->程序包管理器控制台)
在控制台中运行以下命令
1: //Install 2: Install-Package EntityFramework 3: //Or Update 4: Update-Package EntityFramework
现在安装 MvcScaffolding
1: Install-Package MvcScaffolding
如果您还不知道,按 Tab 键可以显示选项,在程序包管理器控制台中随时使用它。
步骤 4:创建模型
在 Model 文件夹中创建一个名为 Models.cs 的 cs 文件(实际上,您应该为不同的模型创建不同的文件,我把它们都放在一个文件中是为了节省我的时间)
Models.cs 包含以下三个模型。
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Web;
5: using System.ComponentModel.DataAnnotations;
6: using System.ComponentModel.DataAnnotations.Schema;
7:
8: namespace TODO.Models
9: {
10: public class Task
11: {
12: [Key]
13: public int TaskId { get; set; }
14: public string Name { get; set; }
15: public string Description { get; set; }
16: public int? StatusId { get; set; }
17: [ForeignKey("StatusId")]
18: public virtual Status Status { get; set; }
19: public virtual ICollection<Note> Notes { get; set; }
20: public DateTime? CreatedOn { get; set; }
21: public DateTime? ModifiedOn { get; set; }
22: }
23:
24: public class Status
25: {
26: [Key]
27: public int StatusId { get; set; }
28: public string Name { get; set; }
29: }
30:
31: public class Note
32: {
33: [Key]
34: public int NoteId { get; set; }
35: public string Description { get; set; }
36: public int? TaskId { get; set; }
37: public DateTime? CreatedOn { get; set; }
38: public DateTime? ModifiedOn { get; set; }
39: }
40: }
数据注解
第 5、6 行:引用,以便我可以使用数据注解,如您在第 12、17、26 和 33 行所见。您可以参考以下文章了解更多关于 Data Annotations 的信息。
定义关系
注意第 18 行,它可以看到此属性应该是 virtual,并带有一个名为 ForeignKey 的属性,包含 FK。还要检查第 16 行,您需要有一个 StatusId 来连接表。
同样,如果您注意到第 36 行,Note 应该属于某个 Task,但不需要有 Note 本身。
我使用了 [Key] 来明确指定主键。
步骤 5:创建控制器和视图
转到程序包管理器控制台,运行以下命令
1: Scaffold Controller Task -Repository 2: Scaffold Controller Note -Repository 3: Scaffold Controller Status –Repository
我使用了 ‘-Repository’ 选项,因为我希望通过仓库来访问数据。当您更改模型并想重新创建控制器或视图时,请使用 ‘-Force’ 选项。
1: Scaffold Controller Task -Repository -Force 2: Scaffold Controller Note -Repository -Force 3: Scaffold Controller Status -Repository -Force
此步骤会自动创建仓库、控制器、DBContext 和视图。
步骤 6:编辑布局
打开 Shared/_Layout.cshtml 并添加链接,以便您可以轻松导航到操作,您可能还想更新应用程序的标题。
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
运行应用程序,它应该可以正常工作。是不是很棒?
注释掉 Notes 和 Tasks 视图的 _CreateOrEdit.cshtml 中显示 ModifiedOn 和 CreatedOn 字段的 div。
转到 NoteRepository.cs 和 TaskRepository.cs,找到 InsertOrUpdate() 方法并进行如下修改
1: public void InsertOrUpdate(Task task)
2: {
3: if (task.TaskId == default(int)) {
4: // New entity
5: task.CreatedOn = task.ModifiedOn = DateTime.Now;
6: context.Tasks.Add(task);
7: } else {
8: // Existing entity
9: task.ModifiedOn = DateTime.Now;
10: context.Entry(task).State = EntityState.Modified;
11: }
12: }
注意第 5 和 9 行,我正在修改 ModifiedOn
和 CreatedOn
,然后保存并更新模型。
更新:根据用户评论添加一些关于第 10 行的信息
第 10 行: context.Entry(task).State = EntityState.Modified; 这是一种告诉 dbContext 某些实体属性已被修改但 SaveChanges() 未被调用的方式。Entity Framework 会负责使用修改后的值更新实体。调用 context.Entry() 会返回一个 DbEntityEntry<TEntity> 对象,该对象提供对 DbContext 正在跟踪的 实体的信息和控制的访问。
简单来说,这是告诉 Entity Framework 使用修改后的值更新实体的一种方法。
您还需要将以下行添加到 tasks 的 _CreateOrEdit.cshtml 中,以保留 CreatedOn
的值。
1: @Html.HiddenFor(m=>m.CreatedOn)
再次运行应用程序,您应该能够添加、更新和删除数据。
这还不是全部,它已经自动为您创建了数据库,您可以检查一下,浏览到 SQLExpress 数据库,在那里您应该可以看到该应用程序的数据库。
检查表、列、主键和外键,它们都已到位,与您在模型中创建的一样。
解释得太多了,然而,根据本文的范围,本文可视为深入研究的起点。在我结束本文之前,最后想告诉您的是一个称为 数据库初始化程序 的东西。
转到 Model 文件夹中的 TODOContext.cs,按如下方式创建 TODOContext
的构造函数
public TODOContext()
{
System.Data.Entity.Database.SetInitializer(
new System.Data.Entity.DropCreateDatabaseIfModelChanges<TODO.Models.TODOContext>());
}
它会像它的名字所说的那样,DropCreateDatabaseIfModelChanges
当您通过添加或删除属性来更改任何模型时,当前数据库将被删除,然后重新创建。如果您在没有此构造函数的情况下修改模型,可能会看到如下错误。
我已经提到数据库将在 SQLExpress 中创建,如果您没有看到数据库在 web.config 的连接字符串中指定的数据库中创建,请不要惊讶。
注意:Entity Framework 将始终尝试连接到本地 SQL Server Express 数据库(.\SQLEXPRESS)。从 EF 5 开始,如果未检测到 SQL Express 正在运行,EF 将使用 LocalDb。如果安装了 SQL Express,即使您使用的是 Visual Studio 2012,SQL Express 也将始终优先。
参考文献
以下是您可以找到更多信息的链接