Managing EntityConnection lifetime - c#

There have been many question on managing EntityContext lifetime,
e.g. Instantiating a context in LINQ to Entities
I've come to the conclusion that the entity context should be considered a unit-of-work and therefore not reused. Great.
But while doing some research for speeding up my database access, I ran into this blog post...
Improving Entity Framework Performance
The post argues that EFs poor performance compared to other frameworks is often due to the EntityConnection object being created each time a new EntityContext object is needed.
To test this I manually created a static EntityConnection in Global.asax.cs Application_Start().
I then converted all my context using statements to
using( MyObjContext currContext = new MyObjeContext(globalStaticEFConnection)
{
....
}
This seems to have sped things up a bit without any errors so far as far as I can tell.
But is this safe?
Does using a applicationwide static EntityConnection introduce race conditions?
Best regards,
Kervin

EntityConnection is documented to be not thread-safe. I think you could pool them, but you cannot use a single, static connection for a Web application, as there will be many threads involved.

If your EF context is Application-wide, consider that user A has made changes (not committed) & user B has committed his changes, all changes will get committed to the database since both user A & B use the same instance
In my project, I did a per WebRequest intance of the EF context - ie. a context object is static from start through end of a web request & all operations in that request work with the same EF context. This has significantly speeded up my processing without the problem mentioned above.
One way to implement this is to use a DI container (I am using Unity) to manage the lifetime of the EF context. The per web request lifetime manager is not given out of the box in Unity, but there are tons of articles out there which show how this can be done.
HTH.

Related

How to manage DbContext in a WPF Applicatoin

I overtook a WPF project where entity framework is used. The person before me used a single global DbContext. After some reading it became clear that this is a bad practice because of several reasons. Now my job is to refactor the project to use a DbContextFactory and create new DbContext per unit-of-work.
One method i.e. SaveSales calls another method IncreaseReceiptNumber. Inside IncreaseReceiptNumber an entry is added to a table and SaveChanges is called. Now inside SaveSales i create a DbContext with using (var clientDB = dbContextFactory.Create() {}.
My question is, in a case like this should I pass the DbContext from SaveSales to IncreaseReceiptNumber or should IncreaseReceiptNumber create it's own DbContext? Or in a more general sense, should every method create a new DbContext or can a DbContext passed on via parameter if it belongs to the unit-of-work?
IMO, there is no single answer to this question. You must decide for each case whether or not the overhead of multiple connections is warranted (overhead is small with pooling, but exists), if the sharing of a single DbContext provides extra benefits (entities already attached), and if sharing makes things more difficult (you're calling the method in a loop, and risk "connection already open" errors) . These factors have to be weighed on a case-by-case basis. For what it's worth, I have done all of these things...use the right tool for the job, as they say.

many DataContext singletons to perform LINQ within a class

For a class that I have, I am noticing I basically have to use the following scenario for each function within a class. Is this inefficient? Is there a better to utilize the DataContext object?
using (var context = new SomeDataContext(getConnectionString))
{
//linq query here
}
It is designed to be used the way you mentioned. You should create a new context each and every time you do something on the database. As #Dan points out, creating a Context is extremely fast and efficient.
That's a correct and proper way to do it because it guarantees that you are disposing of the connection by putting it in a using clause. Instantiating a DBContext is not prohibitively expensive either.
With that said, you are creating one DBContext every time you query your database and disposing of it immediately, so you are not taking advantage of Caching and other niceties offered by the DbContext class.
One "cheap and dirty" way to create only one DBContext per request would be to instantiate one on Application_BeginRequest and store it in the HttpContext.Items collection (basically in a temp Cache) and disposing of it on Application_EndRequest. Each class in your project would then get the current DBContext from the HttpContext.Items cache and use it. The connection will be properly disposed since Application_EndRequest always fires regardless of errors.
A better alternative is to use a Dependency Injection framework (Structure Map, Ninject, etc.) You can google for tutorials on how to do this. SO has several questions that would help you if you are interested in implementing it.
Personal note: Don't worry about any of that stuff unless you noticee that your app is performing too slow to be acceptable. Your current approach is fine.

Using DbContext with only one context

On my latest project, I thought it might be simpler to have only one context throughout the application. I notice that when I load a page that requires more then one query, it may return empty results.
For instance, I have a list of appointments and then a list of sales reps. They show up fine. Then I hit F5, sometimes all will keep being fine, but sometimes the appointment AND/OR rep list will be empty.
Is that a known issue with the single context apps? Is that design a bad one?
Is that a known issue with the single context apps? Is that design a bad one?
I believe yes, with simple web application, you might not see the difference, but with complex web application with many users and required high con-currencies, the problems would be:
DbContext implements Unit Of Work pattern under the hood, with internal cache inside, so keeping global DbContext for long time would cause the memory leak and pull tons of data from database and keep them in memory (internal cache) for the time being.
Think about Unit Of Work is a business transaction, and internal cache in Unit Of Work is just for this transaction, not for global, if the transaction is done, Unit Of Work should be disposed asap.
The best practice for DbContext in web application is keeping lifetime of DbContext as per request. If you use IoC container, most of IoC Container supports per request lifetime management.

What is better: reusing System.Data.Linq.DataContext context or disposing of it ASAP?

If I am using a SqlConnection, apparently the best practice is to dispose of it ASAP, and let the connection pooling handle the details. Should I follow the same pattern when I am using System.Data.Linq.DataContext?
Should I create my context once and pass it along to my methods, or should I get the connection string from my config file and create the contexts multiple times and save on passing the parameters?
Edit: A useful link about identity maps: Architecting LINQ To SQL Applications, part 7
You should keep a data context around only as long as necessary to perform an operation.
The reason for this is that it uses something called an Identity Map so that every time you select say customer 1 you get the same object back. This means it is holding lots of references and will consume more and more memory over time and these results will become increasingly stale.
In the case of a web app it is common to create one per request and the DataContext class is optimised for quick creation.

Enhancing performance on a DAL when it is implemented using Entity Framework

I'm implementing a DAL using the Entity Framework. We have some DAL classes (I call them repositories) instantiating or receiving a context by parameter every time a method is called. I don't like that kind of behavior; I'm not documented about this issue but my common sense says me that context's instantiation consumes too much system resources. So:
Is context's instantiation expensive?
If you've answered "yes" to 1, how would you tackle this problem from a design viewpoint?
If you've answered "yes" to 1, how would you implement the solution in C#?
Which approach do you recommend to implement a DAL for a web application?
my common sense says me that context's instantiation consumes too much system resources
Common sense is nearly useless when it comes to optimization.
What exactly in the constructor of context do you suppose will be problematic? Have you read the source for it yet?
1) Is context's instantiation expensive?
Relative to what? Compared to the amount of time required to establish a database connection? Compared to the time it takes to perform your site's DNS lookup? Compared to the amount of time a browser might spend rendering your page?
The vast liklihood is that context's instantiation is not particularly time consuming compared to the time required to actually retrieve data across the network.
2) If you've answered "yes" to 1, how would you tackle this problem from a design viewpoint?
Use a UnitOfWork abstraction. Each UnitOfWork should contain a single entity context. If this is a web app you should have one UnitOfWork per request.
Context lifetime management is a crucial when using ORMs. The entity framework context in keeps information about loaded entities for lazy loading and change tracking purposes and its memory footprint may grow very quickly. If you don't dispose your context you will essentially have a memory leak.
However, you are correct that keeping the context lifetime too short is not ideal since you would probably like to make use of change tracking.
using (var context = new DataContext())
{
context.Products.Add(product);
context.SaveChanges();
}
The above example shows disposes the context too quickly to take advantage of the change tracking goodies.
For Web applications you should use context per request.
For Win Form applications you can dispose of your context when you move from one form to another.

Categories