EDIT :
This question is not about compiled queries, it is about generating the EF database view at compile time.
From the ADO.NET team blog: Exploring the Performance of the ADO.NET Entity Framework - Part 1:
View Generation 56%– A big part of creating an abstracted view of the database is providing the actual view for queries and updates in the store’s native language. During this step, the store views are created. The good news is there is a way of making view generation part of the build process so that this step can be avoided at run time.
The first database call in my web app takes about 2.5 seconds instead of ~30 ms for subsequent identical calls.
I generated a precompiled view source file using the T4 template from the ADO.NET team blog, but it has made no detectable difference.
The T4 template takes about 2.5 seconds to run and the generated code compiles.
What am I missing?
Fixed it!
The Generated View derived from EntityViewContainer must be in the assembly that contains the STOs Self-Tracking Objects, not the one that contains the edmx model.
Your first call to your application after a build, the web server will have unloaded the application, and the first call "starts" the application again, and everything that is associated with that. This has nothing to do with pre-compiled views. Therefore, the first call will always take longer as the application is loaded.
Incidentally, the same thing will happen on your production server. An idle worker-pool might well unload your application, and the next call will load the application again, taking significantly longer to perform than usual requests.
Related
I have an ASP .Net Core 3.1 Web API. When the API starts, I would like it to read a couple of lookup tables from a database and store them somewhere. These tables contain data that rarely ever changes (titles, countries, languages, etc.) It's data that maybe changes once every few years. So, I would like them to be read and stored upon startup to increase performance, instead of reading the database every time I need this data.
What I did is to create a service that reads all of these lookup tables. Then, in the services' constructor, I call a method in the service which does the actual reading from the database. I then registered this service as a Singleton in Startup.ConfigureServices().
The problem is that the method that does the reading of the database tables is async, and the constructor cannot be async (as far as I understand).
Currently, it's working - the method is called in the service's constructor, which then returns immediately, while the reading of the database tables happens in a separate process. The actual reading only takes like a second or two anyway. However, I don't like this. Another code could run which requires access to this lookup data, but the data might not be ready yet. Ideally, I would like the reading of these lookup tables to complete before any other code is executed. Also, I get a green wiggly line in VS with a warning about this :)
So I'm not sure how to fix it. Is there a best practice for executing code at startup in a .Net Core API?
You can do it in the main method. Since C# 7.1 can application entry point return Task.
Take a look at this example. He runs his migrations in the main method (but he mentions that it's a bit messy, so you can use another approach described in the article). I think you can load your data in the same way.
https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-part-2/
I am working on a C# ASP.NET MVC application that uses Entity Framework 6 (code first). We have a model that has multiple child objects, including one that inherits from a base class. There is a web page that generates a view from this model (after mapping it to a view model). The data is fetched via a call like this:
_context.TableName.Include(includes..).FirstOrDefaultAsync(i => i.Id == id);
There are multiple calls to .Include. Due to the complexity of the model Entity Framework generates a large query.
The first time the code runs, it takes about 4.5 to 5 seconds. Subsequent views of the page result in the data access logic running in around 450 to 550 milliseconds (using the Stopwatch class to profile).
However if I add a loop to repeatedly pull back the exact same data after the initial fetch each call takes around 12 to 15 milliseconds.
I thought this was simply because these calls were obviously returning the object from Entity Framework's cache. That is, no call to the database or materialization required. So I added logic to dispose of the context between each iteration of the loop, with a new context being created each time.
Running this under SQL Profiler showed a torrent of calls to the database from Entity Framework. However the result was the same.
This makes me think there some opportunity to optimize performance that we are missing. Does anyone have any idea as to why there is this discrepancy between how long the data access logic takes to run when the web page is viewed, and when that exact same logic is run (from within the same web page call) in a loop?
Does creating a new context not completely 'reset' Entity Framework? There must be some caching or something else going on to explain the massive performance difference.
Huge thanks in advance.
I'm trying to root cause the issue with slow speed upon sign in in my EF6 web app hosted in azure. With all the research I've done I still don't quite understand why my app is behaving the way it is.
When I first deploy the app, and attempt to sign in, it's slow, this I understand why, and it's acceptable. Subsequent sign-ins and calls are relatively quick. What I don't understand is why if I don't interact with the application for maybe 5 minutes (even though my Azure Web App has Always On set to Enabled and is a Standard pricing tier Web App) the next login will be back down to taking 20+ seconds.
I don't quite understand what "First Run" means when anyone says it in regards to Entity being slow. Does it only mean, "the first time the web app is accessed by ANYONE", or does it mean something like, "When the dbContext is instantiated by ONE SPECIFIC client for the first time, that is THEIR specific first run, and their instance of the app/dbcontext whatever is now warmed up and ready"
The latter doesn't seem to make sense, because I can sign in on one machine, and move to another machine and it will be relatively quick as well.
"First time" means first dbContext use (query) after the application starts. But when app is iddle for some time, app pool is restarted and next time you enter the site it will start again. That's why EF takes time when there is no activity for some time.
Have a look at this post about app pool restart in azure
"First Run" would refer to the first time an EF query is run after the Entity Framework assemblies are loaded in to an app domain.
EF is a fairly large set of assemblies and they take a bit of time to load initially. On the first query they will also do a lot of work verifying the model. A lot of this time can be reduced by Pre-caching the views for the model (MSDN). For databases with a lot of mapped tables and stored procs this can be a quite a long time. I've had projects that could take up to 3 minutes to start up. Precaching reduced that to about 10 seconds. It does add quite a bit of complexity to managing schema changes though.
Before the Entity Framework can execute a query or save changes to the
data source, it must generate a set of mapping views to access the
database. These mapping views are a set of Entity SQL statement that
represent the database in an abstract way, and are part of the
metadata which is cached per application domain. If you create
multiple instances of the same context in the same application domain,
they will reuse mapping views from the cached metadata rather than
regenerating them. Because mapping view generation is a significant
part of the overall cost of executing the first query, the Entity
Framework enables you to pre-generate mapping views and include them
in the compiled project.
We have a rather large EF code-first model that takes a long time to spin up. With EF5 & pre-compiled views, the load time was 30-45 seconds. However, after upgrading to EF6.1, the load time is > 3 minutes. All of this work is happening before it even starts looking at the precompiled views.
By pausing the debugger, I determined that nearly all time is being spent calling SequenceEqual inside the anonymous function created by TablePrimitiveOperations.GetPropertyPathMatcher (see the source). Using a profiler, I've confirmed that over 80% of the time is being spent in this method.
Are there any known fixes to this issue? I've posted it on Connect but I'm wondering if there's a workaround available currently.
It turns out this is an actual bug in EF 6.1.0. MSFT has created a fix which is available in the 6.1.1 beta and will be available in the 6.1.1 release.
I am using Linq2Sql to access my database which is fairly large. (67 tables)
It's quite a pain in the butt to work with currently because it takes ages for the "MSLinqToSQLGenerator" to generate it's classes and finally finish compiling.
Are there any ways to speed up that process?
Like, is it possible to cache its generated output as I'm rarely touching the databasestructure?
Thank you for reading.
Moving your model to a separate assembly.
When your model is included directly in your application's project and you generate views through a pre-build event or a T4 template, view generation and validation will take place whenever the project is rebuilt, even if the model wasn't changed.
If you move the model to a separate assembly and reference it from your application's project, you can make other changes to your application without needing to rebuild the project containing the model.
Note: when moving your model to separate assemblies remember to copy the connection strings for the model into the application configuration file of the client project.
For more Information Check Performance Considerations for Entity Framework