647

使用实体框架 4.1 代码优先而不是模型/数据库优先和 EDMX 图的优缺点是什么?

我试图完全理解使用 EF 4.1 构建数据访问层的所有方法。我正在使用存储库模式和IoC.

我知道我可以使用代码优先的方法:手动定义我的实体和上下文,并使用它ModelBuilder来微调架构。

我还可以创建EDMX图表并选择使用 T4 模板生成相同POCO类的代码生成步骤。

在这两种情况下,我最终都会POCO得到不可知的对象ORM和派生自DbContext.

数据库优先似乎最吸引人,因为我可以在 Enterprise Manager 中设计数据库,快速同步模型并使用设计器对其进行微调。

那么这两种方法有什么区别呢?仅仅是偏好 VS2010 与 Enterprise Manager 吗?

4

10 回答 10

735

我认为区别在于:

代码优先

  • 非常受欢迎,因为铁杆程序员不喜欢任何类型的设计师,并且在 EDMX xml 中定义映射过于复杂。
  • 完全控制代码(没有难以修改的自动生成代码)。
  • 一般的期望是您不会为 DB 烦恼。DB只是一个没有逻辑的存储。EF 将处理创建,您不想知道它是如何完成这项工作的。
  • 对数据库的手动更改很可能会丢失,因为您的代码定义了数据库。

数据库优先

  • 如果您拥有由 DBA 设计、单独开发或拥有现有数据库的数据库,则非常受欢迎。
  • 您将让 EF 为您创建实体,并在修改映射后生成 POCO 实体。
  • 如果您想要 POCO 实体中的附加功能,您必须修改 T4 模板或使用部分类。
  • 由于数据库定义了您的域模型,因此可以手动更改数据库。您可以随时从数据库更新模型(此功能效果很好)。
  • 我经常将它与 VS 数据库项目(仅限高级版和旗舰版)一起使用。

模型优先

  • 恕我直言,如果您是设计师粉丝(=您不喜欢编写代码或 SQL),则很受欢迎。
  • 您将“绘制”您的模型并让工作流生成您的数据库脚本和 T4 模板生成您的 POCO 实体。您将失去对实体和数据库的部分控制,但对于小型简单项目,您将非常高效。
  • 如果您想要 POCO 实体中的附加功能,您必须修改 T4 模板或使用部分类。
  • 由于您的模型定义了数据库,因此很可能会丢失对数据库的手动更改。如果您安装了数据库生成电源组,这会更好。它将允许您更新数据库模式(而不是重新创建)或更新 VS 中的数据库项目。

我希望在 EF 4.1 的情况下,还有其他几个与 Code First 与 Model/Database first 相关的特性。Code first 中使用的 Fluent API 不提供 EDMX 的所有功能。我希望存储过程映射、查询视图、定义视图等功能在首先使用模型/数据库时有效并且DbContext(我还没有尝试过)但它们在代码中没有。

于 2011-03-27T01:27:13.423 回答
139

我认为“编程实体框架”的作者 Julie Lerman 的这个简单的“决策树”应该有助于更有信心地做出决策:

决策树,可帮助选择使用 EF 的不同方法

更多信息在这里

于 2012-10-09T17:45:06.623 回答
52

数据库优先和模型优先没有真正的区别。生成的代码是相同的,您可以结合这些方法。例如,您可以使用设计器创建数据库,而不是使用 sql 脚本更改数据库并更新模型。

当您首先使用代码时,如果没有重新创建数据库并丢失所有数据,您将无法更改模型。恕我直言,这个限制非常严格,不允许在生产中首先使用代码。目前它还不是真正可用的。

代码优先的第二个小缺点是模型构建器需要主数据库的权限。如果您使用 SQL Server Compact 数据库或控制数据库服务器,这不会影响您。

代码优先的优点是代码非常干净和简单。您可以完全控制此代码,并且可以轻松修改并将其用作您的视图模型。

当您创建没有版本控制的简单独立应用程序并在需要在生产中修改的项目中首先使用模型\数据库时,我可以建议使用代码优先方法。

于 2012-01-31T07:38:21.383 回答
38

引用http://www.itworld.com/development/405005/3-reasons-use-code-first-design-entity-framework的相关部分

在实体框架中使用代码优先设计的 3 个理由

1) 不那么粗糙,不那么臃肿

使用现有数据库生成 .edmx 模型文件和相关的代码模型会产生大量自动生成的代码。恳求您永远不要碰这些生成的文件,以免破坏某些东西,或者您的更改在下一代被覆盖。在这个混乱中,上下文和初始化程序也被挤在一起了。当您需要向生成的模型添加功能时,例如计算的只读属性,您需要扩展模型类。这最终成为几乎每个模型的要求,并且您最终得到了所有东西的扩展。

使用代码优先,您的手动编码模型成为您的数据库。您正在构建的确切文件是生成数据库设计的内容。当您想要添加属性或数据库不需要知道的任何其他内容时,没有其他文件并且不需要创建类扩展。只要遵循正确的语法,就可以将它们添加到同一个类中。哎呀,如果你愿意,你甚至可以生成一个 Model.edmx 文件来可视化你的代码。

2) 更好的控制

当您首先使用 DB 时,您将受制于为您的模型生成的内容,以便在您的应用程序中使用。有时,命名约定是不可取的。有时,关系和关联并不是您想要的。其他时候,延迟加载的非瞬态关系会对您的 API 响应造成严重破坏。

虽然对于您可能遇到的模型生成问题几乎总是有解决方案,但首先执行代码可以让您从一开始就获得完整且细粒度的控制。您可以从舒适的业务对象中控制代码模型和数据库设计的各个方面。您可以精确地指定关系、约束和关联。您可以同时设置属性字符限制和数据库列大小。您可以指定要预先加载或根本不序列化哪些相关集合。简而言之,你负责更多的东西,但你可以完全控制你的应用程序设计。

3)数据库版本控制

这是一个很大的。版本控制数据库很难,但使用代码优先和代码优先迁移,它会更有效。因为您的数据库模式完全基于您的代码模型,所以通过对源代码进行版本控制,您可以帮助对数据库进行版本控制。您负责控制上下文初始化,这可以帮助您执行诸如种子固定业务数据之类的事情。您还负责创建代码优先迁移。

首次启用迁移时,会生成一个配置类和一个初始迁移。初始迁移是您当前的架构或基线 v1.0。从那时起,您将添加带有时间戳并标有描述符的迁移,以帮助对版本进行排序。当您从包管理器调用 add-migration 时,将生成一个新的迁移文件,其中包含在 UP() 和 DOWN() 函数中自动更改代码模型的所有内容。UP 函数将更改应用于数据库,DOWN 函数在您想要回滚的事件中删除这些相同的更改。此外,您可以编辑这些迁移文件以添加其他更改,例如新视图、索引、存储过程和其他任何内容。它们将成为您数据库模式的真正版本控制系统。

于 2014-05-09T20:06:20.030 回答
31

代码优先似乎是后起之秀。我快速浏览了 Ruby on Rails,它们的标准是代码优先,带有数据库迁移。

如果你正在构建一个 MVC3 应用程序,我相信 Code first 有以下优点:

  • 简单的属性装饰- 您可以使用验证、要求等属性来装饰字段,EF 建模非常尴尬
  • 没有奇怪的建模错误- EF 建模经常有奇怪的错误,例如当您尝试重命名关联属性时,它需要匹配底层元数据 - 非常不灵活。
  • 合并并不尴尬- 使用 mercurial 等代码版本控制工具时,合并 .edmx 文件很痛苦。你是一个习惯于 C# 的程序员,你正在合并一个 .edmx。代码优先并非如此。
  • 首先对比 Code,您可以完全控制,而无需处理所有隐藏的复杂性和未知数。
  • 我建议您使用 Package Manager 命令行工具,甚至不要使用图形工具将新控制器添加到脚手架视图。
  • DB-Migrations - 然后你也可以启用迁移。这太强大了。您在代码中对模型进行更改,然后框架可以跟踪架构更改,因此您可以无缝部署升级,架构版本会自动升级(并在需要时降级)。(不确定,但这可能也适用于模型优先)

更新

该问题还要求将代码优先与 EDMX 模型/数据库优先进行比较。代码优先也可用于这两种方法:

于 2012-07-26T02:37:25.653 回答
14

我首先使用 EF 数据库,以便提供更大的灵活性和对数据库配置的控制。

EF 代码优先和模型优先起初看起来很酷,并且提供数据库独立性,但是在这样做时,它不允许您指定我认为非常基本和常见的数据库配置信息。例如表索引、安全元数据或具有包含多个列的主键。我发现我想使用这些和其他常见的数据库功能,因此无论如何都必须直接进行一些数据库配置。

我发现在 DB first 期间生成的默认 POCO 类非常干净,但是缺少非常有用的数据注释属性或到存储过程的映射。我使用 T4 模板来克服其中的一些限制。T4 模板很棒,尤其是与您自己的元数据和部分类结合使用时。

模型优先似乎有很多潜力,但在复杂的数据库模式重构期间给了我很多错误。不知道为什么。

于 2012-09-27T04:16:04.717 回答
7

在SP1之前使用大型模型非常慢,(在SP1之后没有尝试过,但据说现在很容易)。

我仍然首先设计我的表,然后内部构建的工具为我生成 POCO,因此它承担了为每个 poco 对象执行重复任务的负担。

当您使用源代码控制系统时,您可以轻松地跟踪 POCO 的历史,使用设计器生成的代码并不容易。

我的 POCO 有一个基础,这让很多事情变得非常容易。

我的所有表都有视图,每个基本视图都为我的外键带来基本信息,并且我的视图 POCO 派生自我的 POCO 类,这再次非常有用。

最后我不喜欢设计师。

于 2011-04-01T07:44:09.440 回答
7

数据库优先方法示例:

无需编写任何代码: ASP.NET MVC / MVC3 Database First Approach / Database first

而且我认为它比其他方法更好,因为这种方法的数据丢失更少。

于 2012-03-10T03:33:30.600 回答
5

恕我直言,我认为所有模型都有一个很好的位置,但我对模型优先方法的问题是在许多大型企业中,DBA 控制数据库,如果不使用数据库优先方法,您将无法获得构建应用程序的灵活性。我参与过许多项目,当涉及到部署时,他们想要完全控制。

因此,尽管我同意 Code First、Model First、Database first 的所有可能变化,但您必须考虑实际的生产环境。因此,如果您的系统将是一个具有许多用户的大型用户基础应用程序,并且 DBA 正在运行该节目,那么您可能会考虑数据库第一选项,这只是我的意见。

于 2014-06-23T15:28:58.683 回答
3

我认为代码优先的优点之一是您可以备份您对 Git 等版本控制系统所做的所有更改。因为您所有的表和关系都存储在本质上只是类的东西中,所以您可以及时回溯并查看数据库之前的结构。

于 2019-06-20T20:25:44.517 回答