بالا بردن سرعت بارگذاری اولیه EF Code first با تعداد مدلهای زیاد
نویسنده: وحید نصیری
تاریخ: ۱۳۹۱/۰۷/۰۹ ۱۹:۸
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
var ms = new MemoryStream();
using (var writer = XmlWriter.Create(ms))
{
EdmxWriter.WriteEdmx(new Context(), writer);
}
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();
EdmGen.exe /mode:ViewGeneration /incsdl:Context.csdl /inmsl:Context.msl /inssdl:Context.ssdl /outviews:Context.Views.cs
using System;
using System.Data.Entity;
using System.Data.Entity.Design;
using System.Data.Entity.Infrastructure;
using System.Data.Mapping;
using System.Data.Metadata.Edm;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace EfUtils
{
public static class PreGeneratedViewsWriter
{
public static void CreatePreGeneratedViewsFile(
this DbContext contextInstance,
LanguageOption language = LanguageOption.GenerateCSharpCode,
string viewsFile = "Context.Views.cs",
string edmxFile = "context.edmx",
string ssdlFile = "context.ssdl.xml",
string csdlFile = "context.csdl.xml",
string mslFile = "context.msl.xml")
{
using (var contextViewsMemoryStream = new MemoryStream())
{
using (var edmxMemoryStream = new MemoryStream())
{
var edmx = createEdmx(contextInstance, edmxFile, edmxMemoryStream);
var mappingItemCollection = createMappingItemCollection(ssdlFile, csdlFile, mslFile, edmx);
generateViews(language, viewsFile, contextViewsMemoryStream, mappingItemCollection);
}
}
}
private static void generateViews(LanguageOption language, string viewsFile, MemoryStream contextViewsMemoryStream, StorageMappingItemCollection mappingItemCollection)
{
var viewGenerator = new EntityViewGenerator // It's defined in System.Data.Entity.Design.dll
{
LanguageOption = language
};
using (var streamWriter = new StreamWriter(contextViewsMemoryStream))
{
var errors = viewGenerator.GenerateViews(mappingItemCollection, streamWriter).ToList();
if (errors.Any())
throw new InvalidOperationException(errors.First().Message);
contextViewsMemoryStream.Position = 0;
using (var reader = new StreamReader(contextViewsMemoryStream))
{
var codeData = reader.ReadToEnd();
File.WriteAllText(viewsFile, codeData);
}
}
}
private static StorageMappingItemCollection createMappingItemCollection(string ssdlFile, string csdlFile, string mslFile, XDocument edmx)
{
var ssdl = edmx.Descendants("{http://schemas.microsoft.com/ado/2009/02/edm/ssdl}Schema").Single();
ssdl.Save(ssdlFile);
var storeItemCollection = new StoreItemCollection(new[] { ssdl.CreateReader() });
var csdl = edmx.Descendants("{http://schemas.microsoft.com/ado/2008/09/edm}Schema").Single();
csdl.Save(csdlFile);
var edmItemCollection = new EdmItemCollection(new[] { csdl.CreateReader() });
var msl = edmx.Descendants("{http://schemas.microsoft.com/ado/2008/09/mapping/cs}Mapping").Single();
msl.Save(mslFile);
var mappingItemCollection = new StorageMappingItemCollection(edmItemCollection, storeItemCollection, new[] { msl.CreateReader() });
return mappingItemCollection;
}
private static XDocument createEdmx(DbContext contextInstance, string edmxFile, MemoryStream edmxMemoryStream)
{
var settings = new XmlWriterSettings { Indent = true };
using (var writer = XmlWriter.Create(edmxMemoryStream, settings))
{
EdmxWriter.WriteEdmx(contextInstance, writer);
}
File.WriteAllBytes(edmxFile, edmxMemoryStream.ToArray());
edmxMemoryStream.Position = 0;
var edmx = XDocument.Load(edmxMemoryStream);
return edmx;
}
}
}
Database.SetInitializer<MyContext>(null);
if (!db_Context.DatabaseExists())
db_Context.CreateDatabase();
اگر فرقی احساس نکردید منتظر نگارش بعدی EF باشید. این مورد رو برطرف کردن:
«significantly improved warm up time (view generation), especially for large models»
using (var ctx = new MyContext())
{
InteractiveViews
.SetViewCacheFactory(
ctx,
new FileViewCacheFactory(@"C:\MyViews.xml"));
} | |
PM> Install-Package EFInteractiveViews
private static bool _isPreGeneratedViewCacheSet;
private void InitializationPreGeneratedViews()
{
if (_isPreGeneratedViewCacheSet) return;
var precompiledViewsFilePath = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName + @”\EF6PrecompiledViews.xml”;
InteractiveViews.SetViewCacheFactory(this, new FileViewCacheFactory(precompiledViewsFilePath));
_isPreGeneratedViewCacheSet = true;
} private static bool _isPreGeneratedViewCacheSet;
private void InitializationPreGeneratedViews()
{
if (_isPreGeneratedViewCacheSet) return;
var precompiledViewsFilePath = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName + @”\EF6PrecompiledViews.xml”;
InteractiveViews.SetViewCacheFactory(this, new FileViewCacheFactory(precompiledViewsFilePath));
_isPreGeneratedViewCacheSet = true;
} InteractiveViews
.SetViewCacheFactory(ctx, new FileViewCacheFactory(new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName + @"\EF6PrecompiledViews.xml")); To Update PM> Update-Package EntityFramework -Version 6.2.0 To install PM> Install-Package EntityFramework -Version 6.2.0
public class MyDbConfiguration : DbConfiguration
{
public MyDbConfiguration() : base()
{
SetModelStore(new DefaultDbModelStore(Directory.GetCurrentDirectory()));
}
} /bin/Debug/MyAssembly.MyNamespace.MyDbContext.edmx
var appDataDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data");
//OR
var appDataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();
Access to the path 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\WorkWithEF2.DataLayer.Context.edmx' is denied.
public class MyDbConfiguration : DbConfiguration
{
public MyDbConfiguration() : base()
{
var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
SetModelStore(new DefaultDbModelStore(path));
}
} public class ExampleContext : DbContext
{
public DbSet<Person> People { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseModel(CompiledModelsExample.ExampleContextModel.Instance);
options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=Test;Trusted_Connection=True;");
}
} CLI: dotnet ef dbcontext optimize -c ExampleContext -o CompliledModels -n CompiledModelsExample Package Manager Console: Optimize-DbContext -Context ExampleContext -OutputDir CompiledModels -Namespace CompiledModelsExample
options.UseModel(CompiledModelsExample.ExampleContextModel.Instance);