代码优先与模型/数据库优先

时间:2011-03-27 00:17:42

标签: entity-framework ef-code-first entity-framework-4.1 poco ef-database-first

有什么优点和优点;是否使用实体框架4.1代码优先于模型/数据库 - 首先使用EDMX图表?

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

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

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

在这两种情况下,我最终得到的POCO对象都是ORM不可知的,而上下文来自DbContext

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

那么这两种方法有什么区别?是仅仅关于VS2010与企业管理器的偏好?

10 个答案:

答案 0 :(得分:675)

我认为差异是:

代码

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

数据库优先

  • 如果您拥有由DBA设计的数据库,单独开发或者您拥有现有数据库,则非常受欢迎。
  • 您将让EF为您创建实体,在修改映射后,您将生成POCO实体。
  • 如果您想要POCO实体中的其他功能,您必须T4修改模板或使用部分类。
  • 可以手动更改数据库,因为数据库定义了您的域模型。您始终可以从数据库更新模型(此功能非常有效)。
  • 我经常在VS数据库项目中使用它(仅限Premium和Ultimate版本)。

先建模

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

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

答案 1 :(得分:126)

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

a decision tree to help choosing different approaches with EF

更多信息Here

答案 2 :(得分:51)

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

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

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

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

我建议您在创建简单的独立应用程序时使用代码优先方法,而不需要进行版本控制,并且首先在需要修改生产的项目中使用model \ database。

答案 3 :(得分:34)

http://www.itworld.com/development/405005/3-reasons-use-code-first-design-entity-framework

引用相关部分
  

使用代码优先设计实体框架

的3个理由      

1)减少臃肿,减少臃肿

     

使用现有数据库生成.edmx模型文件和   相关的代码模型导致一大堆自动生成的代码。   你永远不会触及这些生成的文件,以免你破坏   某些东西,或者您的更改会被下一代覆盖。该   上下文和初始化程序也在这个混乱中被挤在一起。什么时候   您需要为生成的模型添加功能,例如   计算只读属性,需要扩展模型类。   这最终成为几乎所有型号的要求,最终结束   对所有事物都有扩展。

     

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

     

2)更好的控制

     

当你首先进入数据库时​​,你将受到生成的影响   您的模型在您的应用程序中使用。偶尔命名   惯例是不可取的。有时关系和   协会并不是你想要的。其他时候非短暂的   与延迟加载的关系会对您的API响应造成严重破坏。

     

虽然几乎总能找到模型生成问题的解决方案   你可能会碰到,先代码会给你完整而且很好   从开始到粒度控制。你可以控制两者的每个方面   您可以在舒适的环境中使用代码模型和数据库设计   业务对象。您可以精确指定关系,约束,   和协会。您可以同时设置属性字符限制   和数据库列大小。您可以指定哪些相关集合   是要急切加载,或根本没有序列化。总之,你是   负责更多的东西,但你完全控制你的应用程序   设计。

     

3)数据库版本控制

     

这是一个很大的问题。版本控制数据库很难,但首先是代码   并编写第一次迁移,它更有效。因为你的   数据库模式完全基于您的代码模型(按版本)   控制您的源代码,帮助您对数据库进行版本控制。   您负责控制上下文初始化   可以帮助您执行种子固定业务数据等操作。你也是   负责创建代码首次迁移。

     

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

答案 4 :(得分:27)

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

如果您正在构建MVC3应用程序,我相信Code首先具有以下优势:

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

<强>更新

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

答案 5 :(得分:11)

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

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

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

模型第一似乎有很大的潜力,但在复杂的数据库模式重构过程中给了我很多错误。不知道为什么。

答案 6 :(得分:6)

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

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

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

我有一个POCO的基础,这使得很多事情变得非常简单。

我的所有表都有视图,每个基本视图都为我的外键提供基本信息,我的视图POCO来自我的POCO类,这非常有用。

最后我不喜欢设计师。

答案 7 :(得分:4)

数据库第一个方法示例:

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

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

答案 8 :(得分:3)

恕我直言,我认为所有的模型都有一个很好的地方,但我在模型第一种方法中遇到的问题是在许多大型企业中,DBA控制着数据库而不使用数据库而无法灵活地构建应用程序第一种方法。我参与了许多项目,在部署时,他们想要完全控制。

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

答案 9 :(得分:0)

我认为代码的优势之一是,您可以备份对Git之类的版本控制系统所做的所有更改。因为您所有的表和关系都存储在本质上只是类中,所以您可以回到过去,看看以前的数据库结构是什么。