Entity Framework 為什麼First Query很慢?
為什麼實體框架首次加載速度慢?
實際框架在每次編譯後第一次加載速度非常慢,尤其是當您擁有大型模型時。
StackOverflow相關問題
回答
實體框架第一次加載速度非常慢,因為第一個查詢EF編譯模型。如果您使用的是EF 6.2,則可以使用模型緩存,在首次使用代碼時加載預先構建的edmx;相反,EF在啟動時生成它。
public class MyDbConfiguration : DbConfiguration
{
public MyDbConfiguration() : base()
{
var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
SetModelStore(new DefaultDbModelStore(path));
}
}
為了加快早期版本的EF中的應用程序啟動時間,本文中提到了三個建議。
- 使用緩存的DbModelStore
- 生成預編譯的視圖
- 使用NGen生成預編譯的實體框架版本以避免抖動
使用緩存的DbModelStore
它將緩存代碼優先的管道映射並將其存儲在XML文件中。下次啟動應用程序時,EF將反序列化此緩存的映射文件,從而顯著縮短啟動時間。可以使用以下代碼行啟用緩存的DbModelStore。
public class MyContextConfiguration : DbConfiguration
{
public MyContextConfiguration()
{
MyDbModelStore cachedDbModelStore = new MyDbModelStore(MyContext.EfCacheDirPath);
IDbDependencyResolver dependencyResolver = new SingletonDependencyResolver<DbModelStore>(cachedDbModelStore);
AddDependencyResolver(dependencyResolver);
}
private class MyDbModelStore : DefaultDbModelStore
{
public MyDbModelStore(string location)
: base(location)
{}
public override DbCompiledModel TryLoad(Type contextType)
{
string path = GetFilePath(contextType);
if(File.Exists(path))
{
DateTime lastWriteTime = File.GetLastWriteTimeUtc(path);
DateTime lastWriteTimeDomainAssembly = File.GetLastWriteTimeUtc(typeof(MyDomain.SomeTypeInOurDomain).Assembly.Location);
if (lastWriteTimeDomainAssembly > lastWriteTime)
{
File.Delete(path);
Tracers.EntityFramework.TraceInformation("Cached db model obsolete. Re-creating cached db model edmx.");
}
}
else
{
Tracers.EntityFramework.TraceInformation("No cached db model found. Creating cached db model edmx.");
}
return base.TryLoad(contextType);
}
}
}
生成預編譯視圖
視圖生成可以顯著提高啟動性能,因此緩存此步驟是實現良好EF啟動性能的必要條件。有不同的方法來生成和存儲預編譯的視圖,例如;
使用NGen生成EF的預編譯版本
實體框架不在.net Framework的默認安裝中。因此,EF程序集默認不是NGEN,這意味著每次應用程序啟動時都需要對EF代碼進行JITTED。