当看到这个时,我也很震惊。估计绝大多数的人和我一样,这些年来,一直不知道Code Fisrt的真实意义。下面是一篇讲述此情况的译文,欢迎围观,若有翻译不当的地方,请指正,谢谢。如果被惊到了,请点赞!,不满意就拍砖吧。E文好的,可直接看下边的原文。
原文地址:http://blogs.msdn.com/b/adonet/archive/2014/10/21/ef7-what-does-code-first-only-really-mean.aspx
转载请注明出处:http://www.cnblogs.com/VolcanoCloud/p/4483708.html
进入主题之前,我先说一下,我听来的。据说微软最开始想使用的是 Code Only,后来由于他们的营销团队不知道是为了跟Database First 、Model First 对应还是怎么的,就出现了现在的 Code First.
EF7-"Code First only"的真实意思到底是什么?
不久前,我们在博客中写到,我们计划将EF7打造成一个轻量级的、可扩展的版本。它将是一个全新的平台和数据存储(data stores)。我们在北美技术大会(TechEd North America)关于EF的会议中,同样有提及EF7的计划。
在EF7之前,存储(译注:这里当动词用)模型有两种方式,一种是基于XML的EDMX文件格式,一种是基于代码。从EF7开始,我们将不再支持EDMX格式,转而只支持单一的基于代码风格的存储。对于移除对基于XML的EDMX这事,引起很多人的担忧,他们中间,多部分人是源于对“EF7 将只支持Code First“真正含义的误解。
Code First 是一个糟糕的名字
在EF4.1之前,我们只支持Database First和Model First两种工作方式,它他均使用EF设计器提供的方框和直线来表示存储在基于xml格式的.edmx文件中的模型。Database First 从一个已存在的数据库逆向生成一个模型,Model First从EF设计器中创建的模型生成数据库。
在EF4.1中我们引入了Code First. 不幸的是,很多人依据它的名字认为,它是在代码定义模型,然后从模型生在数据库, 事实上,Code First 同样也能用于一个已经存在的数据库或者是生成一个新的数据库。有工具可以支持逆向一个已存在的数据库生成Code First模型,这个工具最初是包含是EF工具集中,后来在EF6.1中被集成到生成EDMX模型的向导中。
换句话来说,Code First 不是相对 Database First 和Dodel First的第三种方式,而是一种可以替代EDMX文件格式的方案。从概念上讲,Code First 同时支持Database First和Model First工作方式。
这的确让人感到混乱,我们取错了名字。 或许叫它“基于代码建模(code-base modeling)”会更清晰些。
是不是使用基于代码建模(code-base modeling)这个名字就更好的呢?
很明显,我们得维护两种不同的建模方式。除此之外,还有别的原因让我们选择在EF7中只支持基于代码建模(code-base modeling)的方式。
1、 源代码控制合并、冲突、代码审审变得困难。当把整个模型存储在一个xml文件时,我们收到了很多开发人员的反馈,模型上一个简单的改动, 将导致xml中产生较大的差异。别一方面,开员人员得合并和重新审查源代码。
2、 开发人员知道如何编写和调试代码。在一些简单的项目中,设计器无可否认的带来便利。然而,很多项目的需求却超了出了设计器的能力范围。遇到这种情况时,需要修改xml文件里的一些东西,但这对多数开发人员来说,这比修改代码要艰难很多。
3、 根据环境自定义模型的能力。我们从客户那里听到这是一个很普遍的需求,比如,在程序运行时你需要指定架构或是表前缀的多租户数据库(Multi-tenant database)。也在可能会根据不同的数据库提供商在运行时轻微调整你的模型。实现这些需求,使用操作基于xml文件的模型会异常艰难。另一方面,在代码中使用条件逻辑来定义模型会很容易实现 。
4、基于代码的模型不会重复。因为CLR类型同样也能构建模型,以及有照顾一般配置(take care of common configration)的约定。 假设一个Blog实体拥有一个BlogId主键。在基于EDMX的模型中,在CLR类中会有一个BlogId属性,一个xml BlogId属性(外加列和映射)以及另外的一些xml内容来标识BlogId作为一个实体键。但在基于代码的模型中,拥有一个CLR类型中的BlogId属性就够了。
5、在代码中提供有用的错误信息更容易。我们都见过”Error 3002: Problem in mapping fragmets starting at line 46...(3002:映射段问题,始于文件46行处...)的错误。这个来自基于EDMX模型报告应该被改进。但是在基于代码的模型中抛出一个配置错误的异常会很容易。
我们可能已注意到,在EF6.x版本,经常会从代码优先管道(Code-First pipeline)中得不到有用的错误信息,这是因为它是建立在为EDMX模型设计的基础设施上。在EF7中,将不会存在这样的情况了。
还有一很重要的功能,可能会被EDMX实现,但这只能在基于代码的模型了。
数据库迁移(Migrations) ,它允许你从基于代码的模型创建数据库,并随着模型的改变而演进。对于EDMX模型,你可以生成一个与当模型匹配的SQL脚本来创建数据库,但是没有办法生成一个包含模型变化的脚本,将模型变化应用于已存在的数据库。
那么,EF7会带来什么呢?
在EF7中,所有的模型均通过代码来表示了。有工具可以从一个已存在数据库逆向生成一个模型(像在EF6.x中那样),你也可以先通过代构建一个模型,然后使用数据库迁移(migrations)技术生成数据库(当模型发生变化时得到更新)。
可能已经注意到,我们在EF7中已经改进了数据库迁移(migrations)技术,解决很多人在团队环境中使用它时所遇到的问题。
怎么解决...
我们已经讨论了所有能想到的,选择只支持基于代码建模(code-based modeling)是一个正解选择的原因。但随之而来的问题产生了。
怎么可视化模型?
EF设计器全是关于模型可视化,同时在EF6.x中,我们有能力为基于代码的模型产生一个只读的可视化模型(使用EF工具集).在EF7中我们同样认为这是一个好的方法。可视化是绝对有价值的,特别是当你有大量的相联的类时。
Roslyn(微软推出的一种编译器)的到来,我们也可以看到拥有一个可读可写的、基于代码模型的计设器。很显然,这不是立马就实现(可能是永远),因为这是一个巨大的工作。但他是我们努力的目标。
怎么解决“从数据库更新模型”场景?
“从数据库更新模型”是这样的一个过程,它允许你立即拉入一个附加的数据库对象(或是修改一个已存在数据库对象)到你的EDMX模型。不幸的是,这个实现,不是一个好的特性。因为你通常会因此丧失了自义定模型的能力,不得不手工去修改xml文件来调整模型。
对于Code First 你可以通过重新运行逆向工程进程,重新生成你的模型,在一些基本的场景中,这种方法表现得很好。但是你关心的是,新生成的代码会覆盖你在模型中自定义部分。很多的自定义,如果不通过修改搭建的代码,将很难适用。
我们在EF7中第一步是,提供一个跟EF6.x中第一次发行的逆向工具一样的工具。在不用重写之前自定义的代码的情况下实现模型的增量更新上面,我们有不少的想法。 从支持简单的添加场景到使用Roslyn编译器修改已存在代码。 我们正在思考这些想法,目前还没有确切的计划。
怎么解决已经存在的模型?
我们不掩饰EF7相对EF6.x所发生的巨大改变,虽然我们保持原有的概念和顶层API,但是底层实现发生了巨大的变化。基于这个原因,我们不建议立马就将已存在模型转移到EF7中来,我们将继续保持开发EF6.x一段时间。
所有的人都需要改变吗?
我们不自欺人,不可能让所有的人都改变,我们知道有一些人对EF设计器和EDMX的喜爱超过了基于代码建模。
与此同时,我们必须平衡时间和资源,我们会分享我们认识最好的特性和功能来帮助开发人员编写一个成功的应用。 这并不是我们轻率,因为对于实体框架的长期发展和用户来说,这是最好的选择。最终的目标是提供一个更快速的、更简单的使用栈,以及减少支持高需求的成本。我们一直朝着这样方向努力。
翻译中,肯定有很多不当的地方,恳请你的指正,同时,请点击下边的推荐来支持。谢谢!希望你有收获。
下面是另一篇MSDN的博客,是中文的,大家也可以去看看,原文地址:https://msdn.microsoft.com/zh-cn/magazine/dn890367.aspx。我摘抄一段我认为对大家有帮助的片段如下:
放弃 EDMX,但继续实行数据库优先
实体框架当前使用两种方法来描述模型。一种使用设计器中的 EDMX;另一种涉及类,即代码优先 API 使用的 DbContext 和映射。如果您使用的是 EDMX 和设计器,则运行时 EF 会在 EDMX 后从 XML 中创建内存中模型。如果您选择代码优先路径,则 EF 会通过读取类(即您提供的 DbContext 和映射)来创建相同的内存中模型。从那以后 EF 的工作方式是相同的,无论您如何描述模型。请注意,通过 EDMX/设计器工作流,您还可以获取 POCO 类和 DbContext 供您在代码中使用。但是由于 EDMX 的存在,因此不会使用它们来创建该内存中模型。当您阅读下文时,理解很重要:EF7 将不支持基于设计器的 EDMX 模型。它无法在运行时读取 EDMX XML 来创建内存中模型。它将只使用代码优先工作流。
当团队发表有关这方面的博文时,引起了很多开发人员的恐慌。部分原因是很多开发人员尚未意识到可以将数据库反向工程到 POCO 类、DbContext 和映射。换言之,您可以从数据库开始来获取代码优先模型。可以通过 2011 年初首次发布的 EF Power Tools Beta 来实现这一目的。该工具受 EF6.1 设计器支持,且肯定也会受 EF7 支持。我已多次提到“代码优先”这一名称有一些迷惑性和误导性。最初它称为“仅限代码”,后来这一名称改为“代码优先”以完美匹配“数据库优先”和“模型优先”。
因此,要从现有数据库开始,您无需设计器或 EDMX。
但是,如果您拥有现有 EDMX 模型,并且不想失去使用设计器的能力,会怎样呢?有一些第三方设计器支持实体框架,例如早已支持 EF 代码优先的 LLBLGen Pro Designer (bit.ly/11OLlN2) 以及 Devart Entity Developer (bit.ly/1yHWbB2)。查找可能提供支持 EF7 的设计器的工具以及其他可能的软件。
还要记住另一个方法:坚持使用 EF6!
实体框架交流QQ群: 458326058,欢迎有兴趣的朋友加入一起交流
谢谢大家的持续关注,我的博客地址:http://www.cnblogs.com/VolcanoCloud/