【问题标题】:EF Model First or Code First Approach?EF 模型优先还是代码优先方法?
【发布时间】:2011-08-13 10:18:19
【问题描述】:

我知道这个问题已经被问过很多次了,因为我已经阅读了很多关于这个主题的关于利弊等的帖子,但我仍然无法决定哪种方法适合我。我对 Web 编程非常陌生,并且具有 SQL DB 管理员/报告写作背景。我决定尝试建立自己的网站,最终可能会有 30 -40 个表格,未来可能会更多。

我已经研究过这两种方法,我更喜欢实体模型方法,只是因为我喜欢设计器的简单性,我喜欢在我面前看到整个模型,它在一张快照中显示了整体画面。另外,我不是一个强大的程序员,我对它使用 DbContext 生成器模板生成 POCO 并在类之间进行所有链接的方式印象深刻。

然而,虽然我喜欢模型优先方法,但我觉得有一些缺点,我不确定它们是否是实际的缺点,或者我只是对模型优先方法和代码优先方法不够了解,因为我'我对此还是很陌生。

我对使用模型优先方法犹豫不决的原因是:

-主要是因为我很难找到有关使用 MVC 3 的模型优先方法的教程。我发现使用 DbContext 的最佳教程是 Julie Lerman 的,但她没有涵盖对使用数据注释很重要的伙伴类并在重新生成 POCO 时进行其他不会丢失的更改。大多数与 MVC 3 相关的教程似乎都使用代码优先方法。大多数人说这是因为导师不想专注于EF,而是在tuts中展示更多的MVC。我个人认为这是因为微软支持 Code First 方法而不是其他方法:)

-如果创建伙伴类是一种好习惯,为什么我找不到很多针对 MVC 3 的教程? Buddy Classes 是视图模型的另一个名称吗?为什么我找不到 Microsoft 提供的任何教程来展示这些伙伴/视图模型与 MVC 3 一起使用?

-我试图在 2 个表之间建立基本的 1 对 1 关系。在模型第一中,您必须将每个表的标识键设置为相同的字段,而不是在其中一个表中使用 FK,当您有 3 个或更多表通过 1 对 1 关系相互链接时,这可能会有点混乱.在代码中,解决此问题的一种方法是使用模型构建器并手动设置它。我认为在 MF 中,您可以通过进入我根本不喜欢做的 XML 来改变关系。

-关于代码优先问题的更多支持/帮助

我对使用 Code First 方法犹豫不决的原因是:

-我是新手编码员。

-我发现随着项目的扩展,跟踪表格和关系变得相当困难。

-没有模型图,我不得不说我真的很喜欢这个想法。

-通过配置类将实体映射到数据库我觉得不可能:)。

-更新表将需要更改代码和数据库。在 Model first 中,只有一个模型更改会自动更新 DB 和 Code,如果你使用伙伴类,你可能也必须更新这些。

此外,现在我看到人们在某种程度上将 Code First 和 Database first 方法结合起来,因为您不会让 Code First 生成数据库,而是手动创建数据库并使用 Code First API 到 EF 来获取它。

所有的选择、缺点和利弊都让我头晕目眩。我只想继续创建我的网站,而不是考虑采用哪种方法。 谁能根据我所说的和/或他们认为将来会成为主流的方法,给我一些关于他们认为最好的方法的见解?

非常感谢戴夫

【问题讨论】:

    标签: .net asp.net-mvc-3 entity-framework-4.1 ef-code-first ef-model-first


    【解决方案1】:

    比较简单。如果您不关心数据库模型,请先使用代码。如果这样做,请先使用模型(或先使用数据库)。这仅取决于您的关注点在哪里,以数据为中心还是以代码为中心。

    【讨论】:

    • 嗨神秘人,我不认为这是关心数据库模型(设计)的情况。归根结底,不是所有方法都建立模型吗?更多的是选择什么工具来构建模型,无论是代码、模型设计器还是通过数据库?
    • @davey - 不是真的。如果您对如何设计数据库模型有非常强烈的看法,那么您将不会使用代码优先,因为代码优先可能不会按照您希望的方式构建模型。代码优先允许您构建您的站点,而无需考虑数据库将如何物理存储它。我无法想象有人会关心数据库的设计方式。
    【解决方案2】:

    如果这是模型优先的主要问题,您可以使用任何版本的 MVC 中的模型优先示例。 MVC 处理“模型”的方式在不同版本之间并没有真正的不同。当然,对视图模型等进行了增强,但您应该可以接受较早的教程。

    我更喜欢代码优先,因为我觉得有数据库模型和域模型,它们有不同的用途。数据库组织是为了数据库的性能和大小,而不是帮助您的应用程序。拥有自己的模型可以让您专注于应用程序中的状态需求,而无需考虑数据库。

    现在,您可以先从模型获取此模型,但您更有可能以这种方式考虑数据库而不是您的需求……尤其是。如果你是这方面的新手。

    只要我的 2 美分。

    【讨论】:

    • 顺便说一句,如果你问我,模型驱动的方法会创建半 POCO,因为它们被大量归因。
    • 嘿 greg 感谢您的回复,我尝试查看较旧的教程,但我更希望看到从头到尾使用 MVC 3 的教程,可能是因为我很懒,我不想在两者之间跳转版本查看旧版本的数据访问层和新版本的前端,视图等 :) 同样在最新版本中,模型首先使用 dbContext 模板生成类,我只发现了一些关于此的 tuts。您提出了一些关于应用程序需求与数据库需求的有趣观点。谢谢
    • MVC 3 教程在发生变化的地方非常有用。他们中的大多数人需要比现在更深入一些。但是,我同意你的观点,如果你能找到你想要的 MVC 3,它是一个更好的解决方案。 :-)
    【解决方案3】:

    我研究了这两种方法,我 只支持实体模型方法 因为我喜欢简单的 设计师和我喜欢看整体 模型在我面前,它显示了 一张快照中的全貌。还, 我不是一个强大的程序员我是 对它产生的方式印象深刻 POCO 使用 DbContext 生成器模板并完成所有 类之间的链接。

    +

    通过将实体映射到数据库 我发现的配置类 不可能:)。

    =先使用模型

    如果创建好友是个好习惯 课程为什么我找不到很多 为 MVC 3 显示这个的教程?是 Buddy Classes 视图的另一个名称 楷模?为什么我找不到 微软的教程展示了这些 与 MVC 3 一起使用的伙伴/视图模型?

    这可能是因为代码优先就像是一个新手。这就是为什么大多数 MVC3 的代码优先教程。模型优先“老得多”,可能是 MVC2 时代最受欢迎的解决方案。

    顺便说一句:你已经知道我的意见,你应该使用什么,你最喜欢什么或觉得最舒服(正如我上次你问这个问题时告诉你的那样),但我只是想在这里添加一些东西 :)

    在 cmets 之后编辑:

    看看这些东西,这将有助于你首先编写代码:

    Creating an Entity Framework Data Model for an ASP.NET MVC Application (1 of 10) Scaffold your ASP.NET MVC 3 project with the MvcScaffolding package

    ++ 来自 MIX11 频道 9 的这些精彩视频:
    Scott Hanselman showing new stuff in his awesome way as usually
    Steve Sanderson showing power of MvcScaffolding

    【讨论】:

    • 嘿 Dampe 我知道我之前问过这个问题的总结版本 :) 在阅读了有关该主题的一些主题并看到此处发布的 3 个答案之后,大多数人似乎倾向于代码优先。这不是我真正想听到的,但我从未见过任何人将模型优先超过代码优先,所以我认为我将遵循规范并使用代码优先。主要是因为我是新手,需要我能得到的所有帮助。我不想在我的项目进行到一半时遇到我无法找到解决方案或任何人求助的模型的问题,因为这种方法被少数人使用。
    • 嗯.. 这也是一个解决方案。如果您切换到代码优先,您将学到一些新东西,而且确实现在更容易获得有关代码优先的提示。 + www.asp.net 有新的大型教程,首先是代码,还涵盖了更新 m:n 关系等场景(我没有在我的解决方案中工作,但这是另一个故事)。也看看MvcScaffolding。我会尝试在我的答案中添加一些链接。
    • 完成。如果你喜欢在学习的同时放松和享受乐趣,我真的建议你先看 Scott Hanselman。然后由你决定。可能会在 asp.net 上深入了解新的 10 部分教程,然后查看有关 MvcScaffolding 的第二个视频,这在 imo 首先编写代码时非常有用。
    • 谢谢dampe,这个周末我会看看这些视频。关于脚手架,我在 MVC 3 工具更新中对此进行了尝试。添加控制器对话框现在支持创建、读取、更新和删除控制器操作和相应视图的全自动脚手架。哪个很甜!
    【解决方案4】:

    这个问题太长了。下次你应该把你的问题分解成多个单独的问题。

    代码优先 x 模型优先 x 数据库优先

    您是一名数据库专家,因此对您而言最好的方法是增量数据库优先方法,您可以在 DB(或 VS 数据库工具)中定义内容并从数据库更新模型。这将使您对数据库有很大的控制权,并允许您以增量方式构建应用程序和数据库。为什么我认为你会喜欢它:

    • 您以前做过 SQL DB Admin - 您可能知道一些关于 DB 以及如何设计它们以获得性能的东西 - EF 不会为您做任何事情。 EF 不会为您创建索引等。
    • 30-40 台意味着您不会一次性构建模型。您将从小型模型开始并不断发展它。一旦您开始在数据库中进行更改或添加初始化数据,您将不希望丢失这些更改和数据。代码优先只允许删除整个数据库并从头开始重新创建它。模型优先允许逐步构建数据库,但您需要 Entity Designer Database Generation Power pack 和 VS 2010 Premium 或 Ultimate(5.000-10.000 美元)。

    更多关于differences between DB first, Model first and Code first。另一个answer describes differences between code-first and working with designer

    DbContext API + 数据库优先 + Fluent 映射

    我认为这是最难的方式。您将首先定义数据库,然后使用 DbContext fluent API 或数据注释来定义映射。这需要很好地理解 EF 以及映射背后的所有原则 + 理解 DbContext API 中使用的默认约定。它将为您提供对映射的良好而明确的控制,但这是最需要做的工作。这绝对是最难走的路。也不应该使用它,因为 DbContext API 主要是为代码优先方法创建的。

    DbContext API x ObjectContext API

    开始使用 EDMX(实体设计器)后,您可以选择使用 DbContext Generator T4 模板或 POCO Generator T4 模板。决定权在您手中 - 您可以使用 DbContext API(第一个模板)或 ObjectContext API(第二个模板),这两种方法都有更好的文档记录,您还可以使用两本好书:

    我对 ObjectContext API 的了解都来自这些书籍、作者的博客和实践 + Reflector。

    DbContext API 目前没有任何书籍。您可以查看一些主要网站以获取有关它的信息:

    我对 DbContext API 的了解都来自这些博客和实践 + Reflector。

    即使您首先使用代码,您仍然可以使用类图来可视化您的类图(它与 EDMX 不同,但足以了解全局)。

    在 Stack Overflow 或 MSDN forum 上进行搜索将为您提供使用这两种 API 时遇到的大多数问题的答案。

    MVC 3

    在 MVC 3 中使用实体框架并没有什么特别之处。用于数据验证注释的伙伴类被认为是不好的做法。伙伴类是用作应用于实体的元数据持有者的单独类。视图模型是用于在控制器和视图之间传输数据的类。视图模型应该针对每个视图使用自己的验证注释,因为在使用相同的实体类型时,您通常需要在应用程序的不同屏幕中进行不同的验证 - 例如,编辑和插入屏幕可能有不同的验证要求。

    尽管它不被认为是一种好的做法,但向实体添加验证是可能的 - 您可以create buddy class for each your entity manually 或者您可以尝试修改 T4 模板以直接为您生成注释(这很难)。

    一对一关系

    是的,EF 要求仅在主键之上创建一对一关系。原因是 EF 不支持唯一键/约束。没有办法解决这个问题,在数据库中使用唯一键不会改变它。

    【讨论】:

    • 嗨 Ladislav,感谢所有 cmets!你是正确的,我很想逐步构建我的应用程序和 Db。我可能会加载大量初始化数据和类型表,并且不想在每次更改架构时都丢失它。您提到 Code-first 只允许删除整个数据库并从头开始重新创建它,但我看到这篇文章 Scott Gu 的博客解释说可以创建数据库然后使用 Code First weblogs.asp.net/scottgu/archive/2010/08/03/…
    • 我在另一篇文章中看到您使用了 DB 优先方法,这对您有什么作用?你有遇到任何问题/退路吗?您也有任何首先使用带有 DB 或模型的视图模型的示例。如何将它“连接”到 edmx 在 .tt 文件中生成的部分类?谢谢
    • @davey:我在以下部分的回答中首先提到了现有数据库的代码:DbContext API + Database-first + Fluent mapping。我只是不先调用该代码,因为它不是代码优先。
    • @davey:如果您发现 EF 生成的查询很慢,数据库优先是好的。您始终可以构建一些存储过程或视图来提高应用程序的性能。我没有使用 View 模型的示例,但是如果您搜索 Stack Overflow,您会发现其中很多,因为这是常见问题。答案很可能会提到您将自己编写视图模型并使用 AutoMapper 在实体和视图模型之间进行映射。
    • Apols 你确实提到了它。没错,在尝试进行流畅的映射时确实看起来很棘手,而且对我来说可能非常困难,因为我对此很陌生。使用自动映射器和创建视图模型的想法听起来像是相当多的额外工作。我喜欢 codefirst 的地方在于,您只需将数据注释添加到您的 POCO 中,而不必担心类被覆盖。我从未使用过 Automapper,并将对其进行研究。我努力在 Stack Overflow 的“View Models”上找到任何示例,其中包含大量关于它们的信息,但没有显示如何在实践中执行此操作的代码示例。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多