【问题标题】:Entity Framework initialization is SLOW -- what can I do to bootstrap it faster?实体框架初始化很慢——我能做些什么来更快地引导它?
【发布时间】:2012-06-01 04:33:25
【问题描述】:

我的 EF 4.3.1 模型有 200 多个表。初始启动很糟糕,几分钟。 DotTrace 捕获的配置文件暗示了框架深处的一些糟糕的算法/可扩展性选择,这可以从那里对许多方法的数百万次调用和 3600 万次 IEnumerable.Contains() 调用证明。这是一个 sn-p,这一切都是由对数据库执行的第一个查询触发的(未来的查询不会这样做并且很好)。

我可以对我的模型做些什么来减轻这种痛苦?我可以以某种方式预编译它吗?更好的是,EF 团队能否解决这些问题或开源框架以便我可以?或者至少修复Warapper 的拼写? :)

编辑:触发此事件的一个特定 EF 调用基本上是 var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault();。 EF Migrations Seed() AddOrUpdate 也有效地生成相同的堆栈。更完整的堆栈跟踪(可能会提供更多上下文)在这里:Fuller Stack Trace

编辑:一些相关链接:

EDIT2:现在他们只是open sourced的代码,看来这一行:

//Filter the 1:1 foreign key associations to the ones relating the sets used in these cell wrappers.
oneToOneForeignKeyAssociationsForThisWrapper =
    oneToOneForeignKeyAssociationsForThisWrapper.Where(
        it => (it.AssociationEndMembers.All(endMember => entityTypes.Contains(endMember.GetEntityType()))));

是需要一些工作的人。它可能不需要使用 O(n^2) 算法,但我还没有仔细观察。

EDIT3:令人高兴的是,EF6 中的工作似乎正在修复此代码:http://entityframework.codeplex.com/discussions/396130

【问题讨论】:

  • 您能porovide 创建此跟踪的 c# 示例代码吗?
  • @Erik Philips:当然(编辑过的问题),但这很简单。
  • 第一个停靠港应该是Performance Considerations (Entity Framework),如果你还没有去过那里 - 检查版本号顺便说一句
  • @AakashM:谢谢。我看了,好好读。至少他们知道这很慢。 ;)
  • 在这个问题中:stackoverflow.com/q/18807355/325727 我遇到了类似的问题,UnityIoC 导致了数百万个框架调用,如 DotNetTrace 所示。不幸的是,这从未解决,我们最终放弃了 Unity。

标签: c# performance entity-framework-4 entity-framework-4.3


【解决方案1】:

已知在 EF6 之前的视图生成对于较大的模型来说很慢。目前的解决方案是使用预生成的视图。这样,您可以在设计时生成视图并在运行时避免这项工作。为此,请下载 EF 电动工具并选择“优化实体数据模型”。它将向您的项目添加一个包含视图的 C# 文件。不利的一面是,每次模型更改时都需要这样做。注意:使用该工具生成视图所花费的时间与在运行时生成视图所花费的时间大致相同(因此有时您需要耐心等待)。这是一篇关于 EF Power Tools 的帖子,可能会有所帮助:http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx

编辑

最近我创建了一个更方便使用的不同解决方案(注意它仅适用于 EF6)-http://blog.3d-logic.com/2013/12/14/using-pre-generated-views-without-having-to-pre-generate-views-ef6/

【讨论】:

  • 谢谢,我会调查并尝试在此处发布结果。您是否认为在未来的版本中可以进行软件改进来加快这个过程,或者计算太多,并且它已经尽可能地优化(暗示我必须把东西切碎或去掉)?
  • 我们正在寻找可能的方法来改进它。
  • 很高兴听到这个消息!祝你好运......如果可能的话,很乐意提供支持。
  • 不,非常感谢您的建议。很高兴看到你们拖网。
  • ...目前我无法使用 EF Power Tools Beta 2,得到“序列不包含任何元素”。
【解决方案2】:

这是另一种方法。它需要一些手动工作,但实际上更适合您想要使用 MsBuild 的场景。您可以手动创建视图,而不是使用 Power Tools(我很遗憾听到它们不适合您)创建视图 - 以下是步骤:

  • 首先,您需要为您的上下文获取工件。您需要所有 - csdl、ssdl 和 msl 文件。您可以使用 EdmxWriter 来获取这些内容。请注意,EdmxWriter 返回一个结合了所有三个文件的 edmx 文件,因此您需要拆分它们。这是此步骤的代码(请注意,命名空间特定于 EF4,如果您正在考虑使用 EF5 和 .NET Framework 4.5,则需要相应地更改它们或仅按本地名称而不是完全限定名称选择元素):

    var ms = new MemoryStream();
    using (var writer = XmlWriter.Create(ms))
    {
        EdmxWriter.WriteEdmx(new Context(), writer);
    }

    ms.Position = 0;

    var xDoc = XDocument.Load(ms);

    var ssdl = xDoc.Descendants("{http://schemas.microsoft.com/ado/2009/02/edm/ssdl}Schema").Single();
    var csdl = xDoc.Descendants("{http://schemas.microsoft.com/ado/2008/09/edm}Schema").Single();
    var msl = xDoc.Descendants("{http://schemas.microsoft.com/ado/2008/09/mapping/cs}Mapping").Single();

    ssdl.Save("Context.ssdl");
    csdl.Save("Context.csdl");
    msl.Save("Context.msl");
  • 当您拥有工件时,您可以使用 EdmGen 工具生成视图。由于这里我们手动进行,您需要在 VS 命令提示符下进行。这是您用来生成视图的命令:
EdmGen /mode:ViewGeneration /incsdl:Context.csdl  /inmsl:Context.msl /inssdl:Context.ssdl /outviews:Context.Views.cs
  • 将生成的文件添加到您的项目中。

如果您想将视图生成与构建系统集成,还有一个更有趣的选项 - 使用 T4 模板。该模板将处理上述步骤。您可以在此处http://blogs.msdn.com/b/adonet/archive/2008/06/20/how-to-use-a-t4-template-for-view-generation.aspx 找到有关此方法的更多详细信息。唯一的问题是该示例不适用于 CodeFirst 方法,因此需要稍作更改,这应该不难。

我实际上为 Code First 创建了 T4 模板。您可以在我的博文中找到下载链接:http://blog.3d-logic.com/2012/05/28/entity-framework-code-first-and-pre-generated-views/

这些模板现在可在 Visual Studio 代码库中使用。以下是包含所有详细信息的帖子的链接:http://blog.3d-logic.com/2012/06/13/entity-framework-codefirst-view-generation-templates-on-visual-studio-code-gallery/

【讨论】:

  • 实际上,在发布此内容后,我正在考虑为 CodeFirst 创建 T4 模板...敬请期待。
  • 我首先为代码创建了视图生成 T4 模板。链接在我的博文中:blog.3d-logic.com/2012/05/28/…
  • Pawel 当前指向 C# T4 模板的链接是:visualstudiogallery.msdn.microsoft.com/…
  • 嗨,帕维尔。此代码需要更改哪些内容才能与 EF6 一起使用? var ssdl = .... 抛出 InvalidOperationException:序列不包含任何元素。
  • @Goran - EF5 视图与 EF6 不兼容,因此您不能使用 EdmGen 为 EF6 生成视图。如果您使用 CodeFirst,我创建了 EF6 特定模板来生成视图 - 请参阅此blog.3d-logic.com/2013/10/17/… 了解更多详细信息。或者,您可以使用 EF Power Tools Beta 4,它允许为 EF6 的 CodeFirst 和 Edmx 创建视图 - 有关详细信息,请参阅此 (blogs.msdn.com/b/adonet/archive/2013/10/12/…) 帖子。
【解决方案3】:

实际上,在当前版本的 Entity Framework 中,视图生成速度非常快。 (6.1) 还有一个更广泛的缓存解决方案正在准备中:https://entityframework.codeplex.com/workitem/1876。你可以等待这个补丁被接受,或者,如果你足够勇敢,你可以自己申请。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多