实体框架初始化是缓慢的 - 我能做些什么更快的引导呢?实体框架初始化是缓慢的 - 我能做些什么更快的

2019-05-14 14:09发布

我的EF 4.3.1模型有200多台。 初始启动是可怕的,几分钟的时间。 一个DotTrace捕获配置文件暗示深藏在框架一些可怕的算法/可扩展性的选择,就证明了数以百万计的呼叫,以多种方法那里和3600万个IEnumerable.Contains()调用。 这里是一个片段,这是所有在数据库上完成(未来查询不这样做,是罚款)第一个查询触发。

我能做些什么,以我的模型,使这个痛苦少? 我能以某种方式预编译呢? 好,可以在EF团队,请解决这些问题,或者开源的框架,所以我可以吗? 或者至少固定的拼写Warapper ? :)

编辑:一个具体EF呼叫触发这基本上是var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault(); var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault(); 。 还一个EF迁移种子()AddOrUpdate有效地产生相同的堆栈。 富勒堆栈跟踪,这可能会给多一点的情况下,是在这里: 富勒堆栈跟踪

编辑:一些相关链接:

  • MSDN: 性能注意事项(实体框架) (感谢@AakashM)
  • MSDN: EF电动工具
  • SO: 实体框架4.1大量的表(715)

EDIT2:现在,他们只是开源,开源的代码,看来这行:

//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

Answer 1:

在预EF6视图生成被称为是更大的机型缓慢。 对于现在的解决方案是使用预生成的意见。 这样,你的看法产生在设计时,并避免在运行这项工作。 要做到这一点下载EF电动工具并选择“优化实体数据模型”。 它可以将一个C#文件添加到您的项目中包含的观点。 不利的一面是,你需要做的每一次它的模式的转变。 注:生成与工具将需要大约相同数量的时间才能生成视图在运行时的观点(所以有时你需要耐心等待)。 这是一个关于EF电动工具后,可能会有所帮助: 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-具有对预先生成的视图,EF6 /



Answer 2:

这里是另一种方式来做到这一点。 这需要一点体力劳动,但实际上更适合您的方案,你想用的MSBuild。 而不是创建与电动工具的观点(我很抱歉,他们没有为你工作),您可以手动创建人 - 这里的步骤:

  • 首先,你需要得到文物为您的上下文。 你需要的一切 - 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办法,因此需要改变这不应该是很难一点点。

其实,我对代码第一次创建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-画廊/



Answer 3:

查看代其实是相当快于实体框架的当前版本。 (6.1)有一个在制备另一个,更广泛的高速缓存解决方案: https://entityframework.codeplex.com/workitem/1876 。 您可以等待接受这个补丁,或者,如果你有足够的勇气,就可以用它自己。



文章来源: Entity Framework initialization is SLOW — what can I do to bootstrap it faster?