首先是实体框架6代码
       

首先从实体框架6代码开始

简介

实体框架6是一个稳定而成熟的框架 ORM 大多数人都应该考虑这一点 .网络应用. 作为一个ORM, 实体框架在你的代码和数据库之间提供了一个抽象层,将你从大部分的数据库设计中解放出来,让你把精力集中在应用程序上. 其他 .网 orm要考虑包括 衣冠楚楚的,一个简单而轻量级的对象映射器,和 NHibernate. 实体框架有几个工作流程可供选择,我们将在下一节中解释, 我们将专注于代码优先.

实体框架6工作流

一旦你选择为你的应用程序使用实体框架, 您必须对使用哪个工作流做出另一个决定.

第一个模型

模型优先工作流允许开发人员使用可视化设计器创建数据库设计,最终在 .EDMX文件. 通过设计师, 开发人员定义所有数据库对象和关系,然后根据模型生成数据库对象. 当没有现有的数据库时,这是一个很好的方法.e. 一个“绿色领域”应用程序)以及当您想要可视化地查看或通信数据库模型时.

数据库的第一

数据库的第一工作流允许开发人员将一个现有的数据库逆向工程成一个 .EDMX文件. 模型和对象是基于数据库自动创建的,这为这种方法提供了最少的灵活性,但也为开发人员提供了最少的工作量. 对于已经拥有数据库的现有应用程序来说,这是一种很好的方法.

代码首先

代码优先工作流允许开发人员从POCO(普通旧CLR对象)生成数据库. 开发人员在类文件中创建数据库上下文和实体,然后从这些文件生成数据库. 对于新应用程序来说,这是一种很好的方法,但它也可以用于具有现有数据库的现有应用程序.

安装

首先从实体框架代码开始, 首先需要安装实体框架NuGet包. 您可以从NuGet包管理器或包管理器控制台窗口完成此操作.

要从NuGet包管理器安装,请遵循以下步骤.

  1. 在Visual Studio中,右键单击解决方案并选择Manage NuGet Packages….
  2. 在搜索框中输入“实体Framework”.
  3. 单击选择结果中的实体Framework,然后单击右侧框架中的Install按钮. 最新的稳定版本将为您预选.

要从NuGet包管理器控制台窗口安装,请遵循以下步骤.

  1. 在Visual Studio, 进入“工具”菜单, 单击“获取包管理器”,然后单击“包管理器控制台”.
  2. 在包管理器控制台窗口中类型为:Install-Package 实体Framework

 

开始

安装了实体框架包之后,我们就可以开始设计我们的实体了. 为数据对象创建单独的类库项目并添加“.数据”添加到应用程序的名称中. 这将数据库逻辑与应用程序的其余部分分离开来,也使项目的目的更加明显.

就本文而言, 我们将创建一个示例MVC 5应用程序,允许用户投票选择辣椒烹饪. 首先,我们将为chili条目创建一个实体. 在ChiliCookoff.数据项目中,创建一个名为“Entry”的新类.然后输入下面的代码.

现在我们将添加另一个新类来捕获选票. 在ChiliCookoff.数据项目中,创建一个名为“Vote”的新类.然后输入下面的代码.

Note that a property named “Id” or + “Id” will automatically be interpreted by 实体框架 as the primary key in the database. 如果您不想遵循此命名约定, 您可以使用“Key”属性强制实体框架使用特定的属性(属性将在本文后面讨论).

创建数据库背景信息

除了拥有定义数据库中表的实体类之外, 实体框架需要一个数据库上下文类来辅助数据库功能,并为开发人员提供自定义行为的方法.

在ChiliCookoff.数据项目, 创建一个新文件夹“DAL”(数据库访问层),然后在DAL文件夹中创建一个新类“ChiliCookoffContext”.然后输入下面的代码.

上面的代码在数据库上下文中有几点需要注意.

  • 的ChiliCookoffContext.c类派生自 Data.实体.DbContext 类,它充当实体类和数据库之间的桥梁.
  • 构造函数的基本覆盖应该包含存储在Web中的连接字符串.配置文件,用于您将使用的数据库. 如果你不指定一个, 实体框架将寻找一个命名与数据库上下文类名称相同的类, 在本例中是ChiliCookoffContext.
  • 您需要为创建的每个实体类定义DbSet属性,以便通过DbContext访问它.

向数据库添加数据

在创建实体和数据库上下文之后, 我们现在可以编写代码向数据库添加数据并从数据库检索数据. 在下面这个非常简单的例子中, 我们正在写代码在HomeController Index ActionResult中添加一个新的辣椒条目,然后从数据库中检索所有辣椒条目. 然后,我们将把chili条目列表传递到主页以便显示.

在首页显示数据库中的chili条目, I added the following code to the home view which passes in a List of type and uses a foreach to iterate over the list and display the entry name.

向数据库添加数据

在构建和运行应用程序时,应该在主页上显示chili条目.

 

但是等等,现在数据库中有数据了数据库是如何创建的? 当应用程序运行并进行数据库调用时, DbContext将本地实体与数据库进行比较,并为您部署或更新数据库模型. DbContext查看DbContext类中定义的所有DbSet属性,并找出如何创建表名, 字段名称, 字段类型, 索引, 等. 这就是代码优先的力量. 您不需要做任何事情来创建数据库或数据库模式. 按照惯例,代码优先足够聪明,可以为您完成这项工作! 注意,他的行为可以使用数据注释或流利的API来覆盖,我们将在后面看到这一点.

现在, 我们可以通过在服务器资源管理器窗口中查看SQL Server数据库来查看创建的数据库.   您还会注意到创建了一个没有指定的表__MigrationHistory. 这是实体框架跟踪应用程序中所有数据库模型更改的地方.

创造的关系

代码首先可用于在数据库中创建表之间的关系,包括一对一, 一对多,多对多. 我们将修改我们的实体,以反映一个更真实的例子,在这个例子中,可以对一个辣椒条目投多次票. 用我们的模型来表示, 我们将添加一个导航属性到条目实体,它将保存与条目相关的Vote实体. 我们还将从Vote实体中删除VotedForId属性,因为不再需要它. 注意,导航属性是使用虚拟定义的,这将允许它利用 延迟加载.

保存对数据库模型的更改

如果您尝试在此时构建并运行应用程序,您将得到一个有趣的错误,如下所示.

发生此错误是因为我们对模型进行了更改,但没有更新数据库模式. 以便更新数据库模式, 我们需要使用代码优先迁移,它允许我们精确地指定要对模式进行哪些更改.

要使用迁移,我们需要使用NuGet Package Manager控制台窗口来启用它们.

  1. 转到“工具”菜单,单击“获取包管理器”,然后单击“包管理器控制台”.
  2. 确保你的默认项目是ChiliCookoff.Data.
  3. 在包管理器控制台窗口中类型为:enable-migrations.

如果一切正常,您应该会看到一条类似于下面的消息,表明该项目已启用迁移.

您还会注意到项目中创建了一个名为“Migrations”的新文件夹和几个新文件. 配置.Cs文件包含迁移用于修改数据库模型的设置. 另一个以“_InitialCreate”结尾的文件表示当前的数据库模型,是第一次迁移.

启用了迁移, 我们现在可以通过在NuGet包管理器控制台窗口中输入“add-migration votechange”来构建我们对Votes实体所做的更改. 一旦脚手架完成, 您应该会看到一个新的迁移文件,它是通过对Entries和Votes表的更改创建的. 注意,迁移文件有一个Up和Down方法. 这被迁移用来对数据库进行更改(Up方法),也可以用来恢复这些更改(Down方法).

有了迁移文件之后,现在可以在NuGet Package manager控制台窗口中输入“update-database”来更新数据库了. 如果一切顺利,您应该会看到一条消息,表明正在应用迁移. 您可以通过返回Server Explorer来检查数据库模型是否已更新, 右键单击数据库, 并选择刷新. 

 

将数据保存到更新的数据库模型

现在我们将修改HomeController中的代码,为我们的chili条目保存一个投票,然后显示该投票. 用下面的代码替换HomeController中的现有代码.

接下来,我们将更改Home Index.CSHTML页面显示辣椒条目的投票者.

现在编译并运行应用程序,您应该会看到该条目和该条目的一票.

流畅的API和数据注释

在使用代码优先时经常使用, 你会遇到代码优先约定不能达到你想要的效果的情况. 在这种情况下,您可以选择使用流利的API或数据注释来覆盖或扩展“代码优先”约定. 作为经验法则,我会尽量坚持使用其中一种,因为当您或其他人在初始开发后回到项目中时,这将更容易找出您的数据库模型. 我的偏好是数据注释,因为它们装饰了实体类的属性,它使您的设计保持在一个地方. 不幸的是, 有些事情无法在数据注释中完成,或者在流利的API中更容易完成.

流利的API

默认情况下,代码首先在SQL Server中创建定义为字符串的NVARCHAR(MAX)属性. 这是对空间的巨大浪费,并且会在较大的应用程序中导致性能问题. 让我们用流利的API重写它. 在开始使用流利的API之前,您需要重写基础OnModelCreating类. 一旦您完成了这些,您就可以使用流利的API来覆盖约定. 在下面的例子中,我们使用HasMaxLenth和HasColumnType方法强制SQL Server中所有VARCHAR列的最大长度为200个字符.

 

数据注释

假设我们计划有一个辣椒条目的搜索页面,允许根据条目的名称进行搜索. 如果我们有大量的条目,这将带来性能问题,因为条目表中的名称列没有被索引(更不用说名称列在SQL Server中被定义为NVARCHAR(MAX),我们使用流利的API进行了修复)。. 为了解决这个问题,我们可以使用“索引”数据注释,如下所示.

命名索引是可选的. 如果不提供索引名称, by default 实体框架 will name it IX_ but I prefer to have my 索引 named in a specific patter of IX_

_

有了新属性, 让我们继续,输入“add-migration entrychange”来构建更改. 一旦脚手架完成, 您应该会看到一个新创建的迁移文件,其中string属性的最大长度为200,name列的最大长度为索引.

 

当代码优先约定不能满足您的需求时,这些只是您可以做的几个例子. 有关更多信息,请查看优秀的实体框架教程部分 数据注释流利的API.

帮助提示

与代码首先一样伟大的是,在团队环境中使用它时可能会遇到一些问题. 如果您有多个团队成员创建迁移并将这些迁移检入到源代码控制中, 你很容易就会到达代码首先无法使用的状态. 为了避免这种情况, 我建议让一个人负责移植,并将其检入到源代码控制中. 这可能很困难,特别是在应用程序设计的早期,因为模型经常更改. 另一个选择当然是良好的沟通. 当团队中的某人创建一个新的迁移并检入它时, 他们应该立即告诉团队中的每个人他们已经这样做了,团队中的每个人都需要尽快从源代码控制处签出并重新构建. 欲进一步阅读,请查看 微软在团队环境中的代码优先迁移 article.

尽管遵循最佳实践, 当你遇到“代码优先”的障碍时,一切都无法正常工作. 在这种情况下,有时按下重置按钮要比尝试放松迁移来确定问题所在更好. 您可以使用我称之为“核选项”的方法来做到这一点,因为它需要删除数据库和所有迁移文件. 很明显, 这应该只在开发早期进行, 还有一周就要开始测试了.

  1. 备份数据库和迁移文件夹,以防万一.
  2. 删除数据库.
  3. 在NuGet Package Manager Console窗口中输入“enable-migrations -force”(只执行一次,注意这会删除配置.c和任何代码种子数据你有在那里)
  4. 从项目中删除Migrations文件夹.
  5. 重建方案.
  6. 重新创建数据库设置,设置在第2步中删除数据库时删除的任何必要帐户.
  7. 在NuGet包管理器控制台窗口中输入“add-migration Initial”,从您的实体类构建一个初始迁移文件.
  8. 在NuGet Package Manager Console窗口中输入“update-database -force”来更新数据库.

最后, 尽管用代码创建数据库很酷, 有时,您希望在创建数据库模型之前直观地查看它. 这样做的一个有用的工具是 实体框架电动工具. 注意,尽管它是一个测试版,但它是一个相当稳定的发行版,并运行良好. 还要注意,安装页面并不表示支持Visual Studio 2015. 你可以找到一个变通的办法 在这里.

结论

实体框架代码优先是一种可靠的方法 .网应用程序,特别是新应用程序. 将c#类转换为数据库设计非常容易,这使得数据库设计经验有限的开发人员非常容易上手.

我们正在招聘开发人员!

来和我们获奖的团队一起工作吧! 我们正在寻找全栈, 汉普顿路和弗吉尼亚州里士满的中高级开发人员职位. 查看我们的职业页面,寻找当前的职位空缺,今天就把你的简历发给我们!

约翰Hadzima
约翰Hadzima核心因素

约翰Hadzima是马拉松咨询公司的解决方案架构师和团队负责人,也是微软认证的解决方案开发人员. 毕业于Old Dominion大学,获得信息系统学士学位, 他在汉普顿路做了20多年的开发人员,专注于使用Microsoft Stack交付解决方案. 如果没有编码, 约翰喜欢冲浪, 滑雪, 骑自行车, 打高尔夫球, 旅行, 陪他的两个儿子.

让我们谈谈你的项目.

我们是一家提供全方位服务的IT和数字营销公司. 我们相信,成功的项目是与我们的客户合作和透明的结果. 您是否在为您的网站或应用程序寻找更好的用户体验? 需要有经验的数据库架构师或业务分析师? 大家一起说!

X