More efficient database access - c#

I am new to databases and linq, so my problem may be considered trivial. I currently start all my db requests in each class with:
DataClassesDataContext db = new DataClassesDataContext()
Then I proceed to make whatever linq request I need within the method and carry on with the main application logic.
Now, two interesting queries:
1) I believe I have seen people wrapping db usage within 'using'. Such as:
using (DataClassesDataContext db = new DataClassesDataContext())
{
...
}
If this is correct, then doesn't it mean that my class can't use a member 'db' variable anymore, but rather those db requests need to be made within each function call? Also, what exactly would happen if I don't use 'using' within the calls?
2) Running my app with SQL Profiler enabled, I see lots of connections opening and closing. Does this means that each DataClassesDataContext call makes a separate connection? It seems inefficient, so is the right way to actually make the DataClassesDataContext object a static within each class being used?

In general, you should use one DataContext per database conversation. Only you can decide exactly what a conversation is, but typically it is a complete request (fetch the user's wish list, or fetch the user's closed orders, for example) that you might think of as a "unit of work."
Typically what happens is something like this:
WishList wishlist;
using(var context = new DataContext(connectionString)) {
var service = new UserWishListService(context);
wishlist = service.GetUserWishList();
}
Also, what exactly would happen if I don't use using within the calls?
The DataContext won't be disposed of properly (unless you've wrapped in a try-catch-finally, but generally you should just use using).
Does this means that each DataClassesDataContext call makes a separate connection?
Not quite. Your application will benefit from the SQL Server ADO.NET provider's built-in connection pooling. Don't worry about this, let the provider manage it for you.
It seems inefficient, so is the right way to actually make the DataClassesDataContext object a static within each class being used?
Absolutely not. DataContexts are not thread-safe (in fact, they are thread-unsafe) and this has "there be dragons" written all over it. Additionally, even a single-threaded context, a static DataContext is a bad choice because the DataContext maintains a cache (for object tracking purposes) of all the entities it has pulled from the database. Over time, the memory consumption will become ginormous.

Since you added the asp.net tag, it means you are using the context within a HTTP call. A static member context is unusable in asp.net because you need to synchronize access to it, and since your data context is required by every call, you can only serve one HTTP response at a time, a scalability fiasco of epic proportions.
This is why data context are created and disposed 'on-the-go'. In fact, the class specifications clearly calls out this use pattern:
In general, a DataContext instance is
designed to last for one "unit of
work" however your application defines
that term. A DataContext is
lightweight and is not expensive to
create. A typical LINQ to SQL
application creates DataContext
instances at method scope or as a
member of short-lived classes that
represent a logical set of related
database operations.
For ASP.Net a sensible 'unit-of-work' context is the HTTP call itself. A longer discussion on this topic can be found at Linq to SQL DataContext Lifetime Management.
The issue of connections open/close is a non-issue. Normally the connections are pooled and the 'opening' is nothing but a re-use of a connection from the pool. If you're opening is heavyweight (fully fledged login) then you're using pooling incorrectly. Comparing Logins/sec and Connection Resets/sec counters will quickly reveal if that is indeed the case.

Related

Is it ok to have one DbContext object for the whole project? [duplicate]

This question already has answers here:
Why re-initiate the DbContext when using the Entity Framework?
(2 answers)
Closed 7 years ago.
I'm working on a c# project which uses Entity Framework 6 for MySql. for Adding objects to the dbContext I use the following approach:
public void Add(User item)
{
using (var ctx = new DbContext())
{
ctx.Users.Add(item);
ctx.SaveChanges();
}
}
Now I need to know if it is ok to have one DbContext object for instance:
private DbContext _ctx = new DbContext();
and change the Add method to
public void Add(User item)
{
_ctx.Users.Add(item);
_ctx.SaveChanges();
}
And then to have another method to dispose the DbContext object and call it when the application is quitting.
Is it a good approach? what are the cons and pros of this approach?
thanks in advanced.
Consider the pros and cons of having a DbContext as a class member:
Pros:
You save one line of code and two braces
Cons:
It is not thread safe. One thread could try to read or write data generated from another thread that may not be in a correct state.
The context will grow in size as objects are added, increasing memory usage.
Someone has to dispose of the containing class.
For web apps it won't matter since each request creates its own objects (unless you cache them in Application or Session)
DbContext is designed to be used per database request. Per MSDN:
A DbContext instance represents a combination of the Unit Of Work and Repository patterns such that it can be used to query from a database and group together changes that will then be written back to the store as a unit.
All in all, the benefit is clearly not worth the cost.
You don't want to do this in web apps. Why? Multiple reasons:
You risk locking all of the requests on a single thread
Sessions can bleed into each other, ending up with one user changing another user's data
While it may seem spinning up multiple contexts affects performance (and makes your coding more involved), underneath the hood things are handled quite nicely.
How about a windows app? Depends. If the app is always connected, it may work in some instances. Certainly makes it easier than spinning up. But, the downside is it consumes resources on the data side whether any work is being done, or not.
In general, I prefer a more optimistic, disconnected system. If that is not the system you need (need, not want), then you might consider it. But, as a rule, I would not have a single instance for an app.

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.

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.

With linq, do you create a single dbContext per request like nHibernate requires?

With linq, do you create a single dbContext per request like nHibernate requires (for performance reasons, creating sessions in nhibernate from what I understand are an expensive call).
i.e. in my asp.net-mvc application, I may for a given action, hit the database 5-10 times on seperate calls. Do I need to create a context and re-use it for the entire request?
DataContexts are intended to be used for a single set of actions interacting with your database. I know, that's vague. Their usage is situational. If you are doing related, or specifically sequential activities, then one DataContext is probably good for you. If you are doing unrelated or parallel activities, consider using a DataContext for each activity.
Consider a few guidelines:
Entities retrieved by one DataContext can only be used (read: updated, deleted, etc.) by that same DataContext. If you need to match up objects across separate DataContexts, you'll have to do something such as running a LINQ query to select objects with the same primary key.
LINQ to SQL uses optimistic concurrency.
Dispose of the DataContext when you are done with it (letting it go out of scope and be garbage collected is fine)
Do not use a static or shared DataContext.
When I did a small app using LinqToSql, I found the app was very sluggish when i did a create-use-dispose of a DatabaseContext object each time I had to hit the database.
When I moved to sharing the DBContext across multiple requests... the app suddenly came back to life w.r.t. responsiveness.
Here's a question that I posted which is relevant

Categories