entity framework初始化是慢的 – 我能做些什么来更快地引导它?

我的EF 4.3.1模型有200多个表格。 最初的启动是可怕的,几分钟。 一个DotTrace捕获的configuration文件意味着一些可怕的algorithm/可伸缩性select深深的框架,从数百万的调用方法,以及3600万IEnumerable.Contains()调用的certificate。 这是一个片段,这是由数据库上的第一个查询触发(未来的查询不这样做,并没有问题)。

在这里输入图像说明

我可以对我的模型做些什么来减轻这种痛苦? 我可以预先编译这个吗? 更好的是,英孚团队可以解决这些问题,还是可以开放框架? 或者至less修复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: 性能考虑(entity framework) (感谢@AakashM)
  • MSDN: EF电动工具
  • SO: 大量表格的entity framework4.1(715)

编辑2:现在,他们只是开源代码,看来,这一行:

 //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)algorithm,但是我还没有仔细观察。

编辑3:令人高兴的是,它看起来像在EF6工作正在修复这个代码: http ://entityframework.codeplex.com/discussions/396130

在EF6之前,视图生成对于更大的模型来说是慢的。 现在解决scheme是使用预生成的视图。 这样,您可以在devise时生成视图,并避免在运行时进行此项工作。 要做到这一点下载EF电动工具,并select“优化实体数据模型”。 它会将C#文件添加到包含视图的项目中。 不利的一面是,每当模型发生变化时,您都需要做到这一点。 注意:要使用该工具生成视图,需要大约相同的时间在运行时生成视图(所以有时需要耐心等待)。 以下是一篇关于EF Power Tools的文章,可能会对您有所帮助: http : //blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx

编辑

最近我创build了一个更方便的解决scheme(注意它只适用于EF6) – http://blog.3d-logic.com/2013/12/14/using-pre-generated-views-without-具有对预先生成的视图,EF6 /

这是另一种方式来做到这一点。 它需要一些手动工作,但实际上可以更适合您想要使用MsBuild的场景。 而不是用电动工具创build视图(我很抱歉听说他们没有为你工作),你可以手动创build它们 – 这里是步骤:

  • 首先,您需要为您的上下文获取工件。 您需要全部 – csdl,ssdl和msl文件。 你可以使用EdmxWriter来获取这些。 请注意,EdmxWriter会返回一个结合所有三个文件的edmx文件,因此您需要将它们拆分。 下面是这个步骤的代码(注意,名字空间是EF4特有的,如果你正在考虑使用EF5和.NET Framework 4.5,你将需要相应地改变它们,或者只select本地名称而不是全名)。
 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 
  • 将生成的文件添加到您的项目。

如果你想将视图生成与你的构build系统集成在一起,还有一个更有趣的select – 使用T4模板。 模板将照顾上述步骤。 你可以在这里find更多关于这个方法的细节http://blogs.msdn.com/b/adonet/archive/2008/06/20/how-to-use-a-t4-template-for-view-generation.aspx 。 唯一的问题是这个例子不适用于CodeFirst方法,因此需要稍微改变一点,这不应该很难。

我实际上为Code First创build了T4模板。 你可以在我的博客文章中find一个链接: http : //blog.3d-logic.com/2012/05/28/entity-framework-code-first-and-pre-generated-views/

Visual Studio代码库现在提供模板。 这里是所有细节的post的链接: http : //blog.3d-logic.com/2012/06/13/entity-framework-codefirst-view-generation-templates-on-visual-studio-code-画廊/

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