I always have seen lots of questions about how to handle the life-cycle of an EF context, but never found a concrete answer to this.
As stated everywhere, context is intended to be used as a unit work and be disposed whenever you finish that work.
So, let's suppose in a program we create a class to manage all the tipical database tasks (create user, update user, delete user, etc..) and in each one we create a context wrapped into a using statement as is intended to be used (at least on all info I have found).
So, now, in our main program in a function we use, let's say, 3 or 4 of those functions. Does that mean we have opened and closed four connections to the database or does EF uses a pooling mechanism to reuse the same connection?
Connecting to the DB is a very consuming process (compared to execurte simple queries) and when using manually connections I tend to pool them to reuse, but with EF I am lost, don't know if I should pool contexts, pool connections and create contexts using that connections or do nothing as the EF will take care of it.
If all your EF instances share the same connection string, then by default it uses a connection pool.
However, I would recommend you to read about the Unit of Work pattern
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
http://www.codeproject.com/Articles/615499/Models-POCO-Entity-Framework-and-Data-Patterns
Related
I want to read / write into a DB from multiple threads.
After some research, I remembered the ACID rules. Do I need to call myTrans = myConnection.BeginTransaction(); every time I want to read/write from inside a thread, in order to keep this Transaction safe from dirty reads/writes (and myTrans.Commit();)? In normal SQL I would use SET TRANSACTION ISOLATION LEVEL SERIALIZABLE to secure it.
How do i do that in C# ?
Thanks in advance
You only need to call BeginTransaction() if you need multiple statements included in the same transaction. It's not normally necessary for ACID rules for single statements, as individual sessions — each call to ExecuteReader()/ExecuteScalar()/ExecuteNonQuery()/Fill() — gives you an implicit transaction.
Even across multiple statements, my tendancy is to put the statements into the same long SQL string (or stored procedure) and include any needed transaction instructions as part of the SQL.
In terms of thread-safety, the best thing to do is use a separate, brand new connection object for each transaction, and wrap it in a using block. Connections are not thread-safe, and so the way to protect them is giving each thread (or transaction within a thread) it's own connection it doesn't have to share.
Even within a thread, it's better NOT to re-use the same connection. There is a feature called Connection Pooling, where the connection object you see in the C# code is a light-weight wrapper for a much-heavier actual connection that is shared from a pool. Trying to re-use the same connection object throughout a thread or application optimizes for the light thing at the expense of the heavy thing.
I understand that DbContext is not thread-safe, plus DbContext caches data and it may leads to data inconsistency when several transactions try to save/commit their own changes into database. Thus, it is highly recommended to inject it per request (here). But I have a situation where only read operations exists (in a stand-alone class library) and there is no transaction or create/update/delete operations.
My question is: Is it safe to inject DbContext as singleton in this situation?
Entity Framework developers explicitly say that DbContext is not thread safe for any operations performed on it, not just write (add, save changes etc) operations, and you should just believe them on that if you don't want to spend days debugging mysterious failures one day.
Even on read operations, EF can perform in-memory write operations on it's internal structures which are not thread safe, you cannot be sure it doesn't do that in any given case. For example, from documentation taking about processing of result set returned by a query:
If the query is a tracking query, EF checks if the data represents an
entity already in the change tracker for the context instance
So if query is tracking query - it checks change tracker for current instance for already existing entity of this type with same key, which means if such entity doesn't exist - it puts it into change tracker. This is write operation, so not safe.
You can say, well, I'll just use AsNoTracking() then. But here is another issue, about conncurrent AsNoTracking queries - EF won't even allow you to execute them anyway. Library maintainer says:
Concurrent use of the same DbContext is not possible - and not just
for tracked queries. Specifically, a DbContext has an underlying
DbConnection to the database, which cannot be used concurrently. There
are other various components at work under the hood which don't
support multithreading.
However, there's nothing wrong with instantiating several DbContexts
and executing queries on them - whether tracking or non-tracking. That
should get you the behavior you're looking for. If you run into any
further issues don't hesitate to post back.
So there are undocumented internal components in play which are not thread safe and you cannot be sure while doing anything on DbContext from multiple threads that you won't hit such components.
I have a unique (or so I think) problem - we have an ASP.NET web app using MVC principles. The project will be at most single threaded (our business requires single point of control). We are using Entity Framework to connect to the database
Problem:
We want to query our database less frequently than every page load.
I have considered putting our database connection in a singleton but am worried about connecting to in too infrequently -- will a query still work if it connected a significant time ago? How would you recommend connecting to the database?
How would you recommend connecting to the database?
Do NOT use a shared connection. Connections are not thread-safe, and are pooled by .NET, so creating one generally isn't an expensive operation.
The best practice is to create a command and connection for every database request. If you are using Entity Framework, then this will be taken care of for you.
If you want to cache results using the built-in Session or Cache properties, then that's fine, but don't cache disposable resources like connections, EF contexts, etc.
If at some point you find you have a measurable performance problem directly related to creating connections or contexts, then you can try and deal with that, but don't try to optimize something that might not even be a problem.
If you want to get data without connecting to the database, you need to cache it - either in memory, in a file or in whatever mean of storage you want, but you need to keep it in front of the DB somehow. There is no other way known to me.
If by connecting you mean building a completely new SqlConnection to your DB, then you can either rely on connection pooling (EF is smart enough to keep your connections alive for some minutes even after you finish your business) or you can just create connections and keep them alive inside your application by not closing them instantly (i.e. keeping track of them inside a structure).
But you should definitely consider if this is REALLY what you want. The way EF does it internally is most of the time exactly what you want.
Some further reading:
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
I have a Windows Service running every ten seconds, in different threads.
This service makes various CRUD operations on a SQL Server 2008 Database onto the same machine.
For each CRUD operation, I put a "using" bracket like this example :
public object InsertClient(clsClient c)
{
using (ClientEntities e = new ClientEntities()) {
e.Clients.AddObject(c);
}
}
I'm concerned about the efficiency of this operations if there is already another thread interacting with the same table. Is it the right way to do this ?
Furthermore, is there any risk of interthread exception with this method ?
Thanks for your help.
No, it's not wrong to have multiple object entities as long as you create and dispose it right away.
Here is the general recommendation from MSDN.
When working with long-running object context consider the following:
As you load more objects and their references into memory, the object context may grow quickly in memory consumption. This may cause
performance issues.
Remember to dispose of the context when it is no longer required.
If an exception caused the object context to be in an unrecoverable state, the whole application may terminate.
The chances of running into concurrency-related issues increase as the gap between the time when the data is queried and updated grows.
When working with Web applications, use an object context instance per request. If you want to track changes in your objects between the
tiers, use the self-tracking entities. For more information, see
Working with Self-Tracking Entities and Building N-Tier Applications.
When working with Windows Presentation Foundation (WPF) or Windows Forms, use an object context instance per form. This lets you use
change tracking functionality that object context provides.
If you are worry about the cost of creating connection every new object entities, since EF relies on the data provider and if the provider is ADO.Net, the connection pooling is enabled by default, unless you disable it in connection string.
Also the metadata is cache globally per application domain, so every new object entities will simply copy the metadata from global cache.
And since EF is not thread-safe, it's recommended to have each object entities in each thread.
Like much of .NET, the Entity Framework is not thread-safe. This means
that to use the Entity Framework in multithreaded environments, you
need to either explicitly keep individual ObjectContexts in separate
threads, or be very conscientious about locking threads so that you
don't get collisions. - MSDN
I got several applications run onto the one machine, also with an MSSQL server on that machine.
Applications are various typed, like WPF, WCF Service, MVC App and so on.
All of them accessing the only database, which is located on the sql server.
The access mode is the simple LinQ-to-SQL class calls.
In each database concact I make some queries, some checks and some db-writes.
My question is:
Can I be sure that calls inside those transaction scopes are not running at the same time (are thread and process safe) by using simple TransactionScope instance?
Using a transaction scope will obviously make a particular connection transactional. The use of transaction scopes in itself doesn't stop two different processes on a machine doing the same thing at once. It does ensure that all actions performed are either committed or rolled back. The view of data each process sees depends on the isolation level, which by default is serializable, which can easily lead to deadlocks. A more practical isolation level is read comitted, preferably with snapshot isolation as this further reduces deadlocks and waits times.
If you want to ensure only one instance of application is doing something, you can use a mutex or use a database lock that all different processes will attempt to acquire and if necessary wait for.