this topic is already widely discussed on stackoverflow and many other blogs, reason to asking question is that i observe this topic was discussed in mostly 3 to 5 years old posts whereas we have EF 6.2 version now, and i expect this may have updates already (there are more reasons you will find in question.
My application has at least 25 Models(Tables) with MySQL as database, models and relations are configured in OnModelCreating, web site is hosted on godaddy and i do not have good access to IIS configurations etc.
Page load time
- First page load: 65 to 70 seconds
- 2nd page load: 1 to 3 seconds
After 10 minutes delay again it will takes 70 seconds to load page. Please note that i tested it in different environments, like using different internet connection. There are no pictures on the page, and test page has only 5 rows of data with two columns (calling simple method db.Test.ToList();)
While searching internet i found that is common problem with EF so i tried fixing it, while taking help from posts 3 Steps for Fast EntityFramework and Pregenerate Model and View Cache
After this fix
- First page load: 64 to 67 seconds
2nd page load: 1 to 3 seconds
// DbConfiguration constructor public MyDbConfiguration { var path = Path.GetDirectoryName(this.GetType().Assembly.Location); SetModelStore(new DefaultDbModelStore(path)); } // DbContext private static DbMappingViewCacheFactory viewCacheFactory; private static DbMappingViewCacheFactory ViewCacheFactory { get { if (viewCacheFactory == null) { var path =ConfigurationManager.AppSettings[GlobalContextConfig.EFCacheFolder]; viewCacheFactory=new FileViewCacheFactory(path+"Budget.Context.MyDbContext.xml"); } return viewCacheFactory; } } public MyDbContext() : base("name=MySqlConnectionString") { // In case i need to update xml for now i delete the old file manually InteractiveViews.SetViewCacheFactory(this, ViewCacheFactory); Database.SetInitializer<MyDbContext>(null); this.Configuration.ProxyCreationEnabled = false; this.Configuration.LazyLoadingEnabled = false; this.Configuration.AutoDetectChangesEnabled = false; this.Configuration.ValidateOnSaveEnabled = false; }
It was improved but not enough, I want to know if these issues are updated in EF 6.2.0 or method of fixing it has changed, or any thing im doing wrong/should check.
I also installed EF 6.1.X and generated views by right clicking Contaxt file and choosing Entity Framework > Generate View in the manu
Results:
- First page load: 40 to 50 seconds
- 2nd page load: 0 to 1.5 seconds
That's quite amazing, EF 6.1.X is much faster than EF 6.2
Build and deployed as Release package with debug=false
For test purpose i also uploaded asp.net application without Entity Framework, it takes 8 to 13 seconds to load for first time, and second load takes in less than 1 seconds
The answer is yes,
EF 6.2 has introduced a Model Cache
You can learn more here: https://codeopinion.com/entity-framework-code-first-model-cache/
I assume you read the performance considerations:
https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/performance-considerations
I am personally struggling with these issues aswell. I resorted to a) creating custom SQL for some queries. and b) I created a warmup mechanism. There is also an option to precompile queries which might help.
The warmup mechanism runs at the start of the application on a seperate thread. There it does a very simple request to the database, this forces the creation of the model, and 'triggers' the initial startup delay for all queries. After that query has ran (it takes a couple seconds) a flag gets set. All other operations wait for the flag being set before running. Especially in a multithreaded scenario this helps a lot.
I found out that the startup delay was created per thread. This means that if the delay is let's say 2 seconds, running 3 threads who all create a context and try to run some linq, make the whole application wait for 6 seconds.
Note that by creating custom queries, one must return all fields for the entity to be created;
I have not tested this matter fully - so take some time to test. This is just a heads up.