EF第一次加载较慢的原因以及解决方法(汇)(转)

1,798次阅读
没有评论

因为遇到这个问题,查找了一番,根据这篇文章做出修改确实有很不错的效果,特此记录一下。本篇转载来源:https://blog.csdn.net/ma15732625261/article/details/72541184

为什么会慢:

在应用程序中定义的每个上下文,其首次使用时,JUST-INTIME编译器:Entity Framework都会根据数据库中的信息在内存中生成一个映射视图(mapping views),这个操作非常耗时。定义的每一个上下文都会受此困扰。

1、Code First第一次启动会对比程序中的Model与数据库表(database initializer ),生成Model与数据库的映射视图。
2、EF从6开始安装.net Framework默认不会安装EF。因此EF程序集就没有生成本地镜像,这样每次程序启动,EF的代码都会通过just-in-time (JIT) compiler把MSIL中间代码编译成本机能识别的本地代码(存在程序运行的进程的内存中),当程序进程被终止它将回收(例如:iis程序池回收,程序池默认是按需触发运行的,没人访问它就不启动了)。由于EF框架还是比较大的,EF6文件大小到4-5M了,所以每次启动都要重写编译本地代码有比较明显的性能影响。

3,MVC的程序第一次访问比较慢的的问题由于第一次是要处理视图文件.cshtml(生成为.cs文件)、加载引用的dll程序文件和初始化程序池等等

解决一、EF暖机操作

在应用程序初始化时一次性触发所有的DbContext进行mapping views的生成操作——调用StorageMappingItemCollection的GenerateViews()方法。

using (var dbcontext = new CnblogsDbContext())
{
    var objectContext = ((IObjectContextAdapter)dbcontext).ObjectContext;
    var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
    mappingCollection.GenerateViews(new List<EdmSchemaError>());
}

对于ASP.NET应用程序 ,可以将上面的代码放在Application_Start或者PreApplicationStartMethod中执行。

解决二、application Initialization

iIIS8内置功能,安装Application Initialization Module for IIS 7.5。

EF第一次加载较慢的原因以及解决方法(汇)(转)
EF第一次加载较慢的原因以及解决方法(汇)(转)


解决三、 用Ngen安装生成EF的本地镜像

Ngen创建本机映像native-code并将其安装到本机映像缓存中,可通过内存映射被多个进程共享

本机影像生成器(Ngen.exe)工具使用实践 
NGen是个什么东西?

解决四、 禁用第一次ef查询对表__MigrationHistory的问题

使用了ef的Code first会在第一次ef查询的时候会对__MigrationHistory访问,是为了检查数据库和model是否匹配,以保证ef能正常运行。通过监测会先执行下面的sql:

SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM [dbo].[__MigrationHistory] AS [Extent1]
)  AS [GroupBy1]
GO

SELECT TOP (1) 
[Extent1].[Id] AS [Id], 
[Extent1].[ModelHash] AS [ModelHash]
FROM [dbo].[EdmMetadata] AS [Extent1]
ORDER BY [Extent1].[Id] DESC
GO

这段sql语句其实中只是在开发的时候有用,发布到生产环境,可以把这个给禁用了以提高性能。解决办法:
Application_Start加代码

Database.SetInitializer<上下文>(null);

afirefish
版权声明:本站原创文章,由afirefish2019-02-26发表,共计1732字。
转载提示:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
载入中...