【问题标题】:Is there a performance difference between Model First and Code First in MS Entity Framework 4.1?MS Entity Framework 4.1 中的 Model First 和 Code First 之间是否存在性能差异?
【发布时间】:2011-07-16 11:31:27
【问题描述】:

我正在开始一项新的开发,我计划在 Entity Framework 4.1 中使用 Code First。

我之前使用过 Model First,发现在加载上下文、第一次调用 SaveChanges() 以及 Association Fix-up 的位置方面存在一些性能问题。

有没有人比较这两种技术的性能 - 或者说,它们微不足道?

谢谢。

【问题讨论】:

  • 根据我的经验,代码优先实际上比模型优先(或者更确切地说,数据库优先)慢。但这最终没关系,因为您可以稍后切换 ORM 提供程序。 CF 方法让我感到困扰的是,如果您的数据库足够复杂,您最终会想要更新它,并且没有增加数据库的机制 - 即使您添加了完全不相关的列。
  • 谢谢格莱诺。我怀疑任何性能差异都可以忽略不计-只是想听听任何动手经验。一般来说(MF 和 CF),EF 在处理模式更新方面很差(删除和重新创建数据库并不优雅),尽管有一些方法可以提取更改。我当然会尽可能避免修复代码 - 这可能是一场噩梦。
  • 模型优先不只是一种设计时策略吗?最后,您从 T4 模板创建模型类和 DbContext。在运行时,无论您是手写这些类(代码优先)还是从设计工具自动生成(模型优先),都没有关系。
  • @Slauma:这是正确答案;)
  • @Slauma @Ladislav。谢谢,我不确定。我找到了一篇文章msdn.microsoft.com/en-us/magazine/hh148150.aspx,其中指出“无论您选择哪种建模技术——数据库优先、模型优先或代码优先——一旦你创建了一个模型,当你开始查询、交互和通过模型的类使用实体框架运行时持久化实体”。所以这很清楚。谢谢大家。

标签: performance entity-framework entity-framework-4.1 ef-code-first


【解决方案1】:

我相信性能上完全没有区别。代码优先、模型优先、数据库优先是设计时的建模策略。对于 Model-First 和 Database-First 实体类,DbContext 将使用 T4 模板创建。在运行时,EF 4.1 只适用于这些类,它们来自哪里并不重要 - 手写(代码优先)或从 T4 模板自动生成(模型优先,数据库优先) .

另外请记住,在我看来,Model-First 给您带来的好处是相当有限的:您只能在 VS2010 的设计图面上创建模型类。但另一方面也有更多的缺点:default T4 模板在从模型创建代码时不是很精细。例如:它不会将MaxLength 属性放在属性上,它总是在关系的两侧创建导航属性(您通常不想要并且需要双方)以及DbContext 中覆盖的OnModelCreating 方法只包含单行throw new UnintentionalCodeFirstException();,这并不是特别令人印象深刻。您可以修改 EDMX 文件的模板和 CSDL 部分,以便在生成模型类和 DbContext 时获得更多粒度(感谢 Ladislav 在下面对此选项的评论)。

换句话说,您很可能必须调整生成的代码(添加属性、删除不需要的导航属性、添加 Fluent 映射代码等)才能获得您想要使用的微调模型类。完成此操作后,很难在模型设计器中进行任何更改,因为 DbContext 生成器将覆盖您在代码中手动进行的所有更改。

在我看来,EF 4.1 的 Model-First 仅在您已经在设计器界面中设计了模型(例如从较旧的 EF 4.0 项目中设计)并且您希望将项目迁移到 EF 4.1 时才有用。在这种情况下,DbContext 生成器可能有助于为您创建 initial 代码。从那时起,我将继续单独使用代码,这意味着:使用 Code-First。如果您从一个新项目开始,我会从一开始就更喜欢 Code-First。即使您真的想要或需要在 Code-First 中的设计器表面中的模型的这种可视化表示,您也可以简单地从您的 DbContext 创建一个 EDMX 文件并在 VS2010 中打开它以显示您的模型类及其在设计器中的关系:

using (var context = new MyDbContext())
{
    using (var writer = new XmlTextWriter(@"c:\MyModel.edmx", Encoding.Default))
    {
        EdmxWriter.WriteEdmx(context, writer);
    }
}

编辑

实际上,EF 4.1 有一点可以识别模型是来自模型优先(即 EDMX 模型文件和设计器表面)还是纯代码优先模型 - 这就是连接字符串。如果您从 Model-First 创建模型,您会得到一个连接字符串,其中包含对模型元数据文件的引用,如下所示:

<add name="MyConnectionString" 
     connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl
         |res://*/Model.msl;provider=System.Data.SqlClient;
         provider connection string=&quot;data source=.\sqlexpress;
         initial catalog=MyDb;integrated security=True;
         multipleactiveresultsets=True;App=EntityFramework&quot;"
     providerName="System.Data.EntityClient" />

而对于 Code-First,只需使用没有元数据引用的“普通”连接字符串:

<add name="MyConnectionString" 
     connectionString="Server=.\SQLEXPRESS;Database=MyDb;Trusted_Connection=Yes;"
     providerName="System.Data.SqlClient" />

现在,您也可以毫无问题地将第二个简单连接字符串用于通过 Model-First 创建的模型。但是上面的代码 sn-p(从 DbContext 创建一个 EDMX)会抛出一个异常,第一个连接字符串告诉 WriteEdmx 只能用于代码优先,但不能用于模型优先或数据库优先。所以显然 DbContext 以某种方式处理或存储来自连接字符串的元数据信息。

如何解释这个?是不是说在内存中建立模型时,它实际上使用了连接字符串中指定的 EDMX 文件中的数据?在这种情况下,理论上代码优先和模型优先之间可能存在性能差异(至少在模型构建时)。但我认为元数据实际上并没有被处理。但是提到的异常有点奇怪。当我的模型来自 Model-First 时,为什么 EF 4.1 阻止我创建 EDMX 模型文件?也许只是为了避免可能的混淆和弄乱两个 EDMX 文件?我不知道。

【讨论】:

  • +1,但我认为您错过了 Code-First POCO 在运行时所经历的一些魔力。与实际的网络延迟相比,这种魔法显然很便宜,但该模型还必须根据数据库存储的校验和进行验证,这显然会产生额外的处理和网络成本。但是,和大多数人一样,我可以忍受这一点,因为它节省了开发人员的时间。但是由于 CF 鼓励您使用这些 POCO,因此当您以后想要更新表定义时(例如发货产品、添加表、更改校验和、中断产品),您可能会遇到困难。
  • @Gleno:模型仅在应用程序启动后第一次使用上下文时验证一次。此外,该功能可以关闭。
  • @Slauma:即使首先使用模型,您也可以获得所需的任何粒度,并且可以添加所需的数据注释,但它需要在 T4 模板中进行一些更改,并且大多数情况下需要在 CSDL 部分手动更改XML(结构注释)。
  • @Ladislav:我明白了,我并没有考虑修改模板和 EDMX。我已经在我的回答中添加了一个关于这个的注释。
  • @Sluama @Gleno @Ladislav 感谢大家非常有用的 cmets。我不知道 EdmxWriter 所以这很有趣。我只想使用 T4 模板来提高工作效率,因此拥有 EDMX 文件很重要。
【解决方案2】:

是的,Model First (EF 4.0) 和 Code First (EF 4.1 - 4.3.1) 之间存在性能差异:

  • 你不能pre-generate internal query views。这意味着每次 EF 尝试运行其第一个查询(每个应用程序域)时,都需要执行昂贵的操作来生成这些视图,具体取决于您的模型复杂性。这通常会影响应用程序的启动性能,并使调试非常烦人。

  • 您不能使用compiled queries。这会严重影响经常使用的查询,尤其是复杂的查询。它可能成为严重的瓶颈和 CPU 占用。只有 EF 5.0(将包含在 .NET 4.5 中)通过自动编译所有查询(包括 Code First 查询)解决了这个问题。

【讨论】:

    【解决方案3】:

    根据this benshmark。它还说 EF Model First 总是比 EF Code First 快。

    【讨论】:

      猜你喜欢
      • 2012-05-15
      • 2023-04-02
      • 2020-06-15
      • 2011-08-01
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 2011-09-19
      • 1970-01-01
      相关资源
      最近更新 更多