Entity Framework: Calling 'Read' when DataReader is closed - entity-framework

Entity Framework: Calling 'Read' when DataReader is closed
I am getting this problem intermittently when i pound my service with parallel asynchronous calls.
i understand that the reader is accessed when calling .ToList() on my defined EF query.
I would like to find out what is the best practice in constructing EF queries to avoid this, and similar problems.
My architecture is as follows:
My Entity Data Layer is a static class, with a static constructor, which instantiates my Entities (_myEntities). It also sets properties on my entities such as MergeOption.
This static class exposes public static methods which simply access the Entities.
public static GetSomeEntity(Criteria c) {
...
var q = _myEntitites.SomeEntity.Where(predicate);
return q.ToList();
}
This has been working in production for some time, but the error above and the one here happen intermittently, esp under heavy loads from clients.
I am also currently setting MultipleActiveResultSets=True in my connection string.

And that is the source of all your problems. Don't use shared context and don't use shared context as data cache or central data access object - it should be defined as one of the main rules in EF. It is also the reason why you need MARS (our discussion from previous question is solved now). When multiple clients executes queries on your shared context in the same time it opens multiple DataReaders on the same db connection.
I'm not sure why you get your current exception but I'm sure that you should redesign your data access approach. If you also modify data on shared context you must.

The issue may come from the connection timeout when trying to get a huge amount of data from your database, so trying to set the connection timeout in your code as below:
Entity 5
((IObjectContextAdapter)this.context).ObjectContext.CommandT‌​imeout = 1800;
Other Entity:
this.context.Database.CommandTimeout = 1800;

Related

Problem with the concept of scope in Dependency injection when using EF [duplicate]

This question already has answers here:
What is the best practice in EF Core for using parallel async calls with an Injected DbContext?
(2 answers)
Closed last year.
I have a problem with the concept of scope in dependency injection. I have registered my db context as a scope and And I save the user activity in a table using an asynchronous method without using "await".
// In Startup:
services.AddScoped<IDbContext, StorageSystemDbContext>();
services.AddScoped<IUserActivityService,UserActivityService>();
// In UserActivityService:
public async void LogUserActivityAsync(string controllerName, string actionName, ActionType actionType = ActionType.View, string data = "", string description = "")
{
await InsertAsync(new UserActivity
{
ControllerName = controllerName,
ActionName = actionName,
ActionType = actionType,
CreatedDateTime = DateTime.Now,
Description = description,
UserId = (await _workContext.CurrentUserAsync())?.Id
});
}
//In Controller:
_userActivityService.LogUserActivityAsync(CurrentControllerName, CurrentActionName,data);
I get the following error when I call same action twice immediately:
InvalidOperationException: A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
I expected a new db context to be created with the second request, depending on the type of db context dependency registration, but according to this error, a new context was not created for the second request and used the previous one.
What is the reason for this?
I'm using Asp Net.Core MVC and EF in .Net Core 5
An injected DbContext into a service regardless of scoping will be one single reference when constructor injected. Calling multiple methods in that service will always use the same instance. AddedScoped with ASP.Net will scope the services (and DbContext) to the web request. This is the recommended scoping for a DbContext to ensure any entities loaded during a request can ensure that they are all tracked by the same DbContext instance and that DbContext should be alive for the life of that request. (i.e. to provided lazy loading support if needed) A Transient scoped dependency would mean the DbContext passed to 2 different services would be distinct references. This leads to problems where Service A calls another service to retrieve entities that it wants to associate with an entity it loaded and is trying to update. These entities are associated to a different DbContext resulting in errors or issues like duplicate data being created.
Even with a transient scope DbContext you would still have the exact same problem trying to run two calls from the same service in parallel, and there are many good reasons referenced in the comments not to use un-awaited async calls to do so. Even if your intention is to await multiple calls together, the only way to enable something like would be to internally scope the DbContext within the method call itself. This would typically involve injecting a DbContextFactory type class rather than a DbContext into the service, where the DbContextFactory is a dependency that can initialize and provide a new DbContext; Then:
using (var context = _contextFactory.Create())
{
// operations with DbContext. (context)
}
Even then you need to consider the DB synchronization guards like row and table locks / deadlocks which could rear their heads if you have a significant number of operations happening in parallel. Keep in mind with web applications the web server can be responding to a significant number of requests in parallel, each of which could be kicking off these processes at any time. (Works fine during development with 1 client, crawls/dies out in the real world.)
I found the answer here:
https://stackoverflow.com/a/44121808/4604557
If for some reason you want to run parallel database operations (and think you can avoid deadlocks, concurrency conflicts etc.), make sure each one has its own DbContext instance. Note however, that parallelization is mainly useful for CPU-bound processes, not IO-bound processes like database interaction. Maybe you can benefit from parallel independent read operations but I would certainly never execute parallel write processes. Apart from deadlocks etc. it also makes it much harder to run all operations in one transaction.

Having static Repository class in a webforms project reuses entity framework connections?

I have a
public static class Repository
in my webforms project.
In the static block of that class I setup my entity framework entity object:
private static readonly ProjectEntities db;
static Repository()
{
db = new ProjectEntities("Name=ProjectEntities");
}
Then I setup some public static methods like this:
public static Order GetOrder(int orderID)
{
return db.Orders.First(o => o.OrderID == orderID);
}
The problem is that when for instance deletions fails (because of some constraint), I randomly gets some clues about that in subsequent connections, coming up as exceptions as a result of queries that should be innocent. For instance, exceptions about deletions as a result of select queries.
I never
db.AcceptAllChanges();
upon any exception, and I should not have to, because across page accesses, there should be no trace of failed queries. Or should it? Is the cleaning responsibility on me?
Those problems should not be because of me using static (please say it is not like that), so is it related to entity framework connection pooling?
Generally speaking the entity framework context is meant to be short lived - i.e. it is generally regarded as a unit of work whereby you create it for a particular task and dispose of it at the end. It's a light weight object, and should be used in this way.
You issue is as a result of the object being long lived (i.e. in a singleton shared across requests). In this case the internal state of the context is becoming invalid - i.e. you try to delete something, it cannot persist those changes to the database, and is therefore in an invalid state.
You could probably resolve your issue by calling the refresh method before making use of the object in every case - this will cause the object to update its state based on the database - but this will probably cause other issues.
However, this is the wrong thing to do - the context should be created, used and disposed per request.
Hope this helps.
I would seriously suggest you investigate the lifecycle management of your context object.
Have a look at this excellent answer as to what your options are.

Does Entity Framework store it's DbContext along with cached query plans?

In my web application, we are using a per request DbContext. We create the DbContext in Application_BeginRequest(), store it in HttpContext.Items, and then call Dispose on it in Application_EndRequest().
We make the current context available through a wrapper class DatabaseContext.Current property.
Sporadically, when executing a query against this database context, we get the following exception:
"The ObjectContext instance has been disposed and can no longer be used for operations that require a connection".
I've searched our code for any possibility that we are calling Dispose on the context elsewhere....we aren't.
A query that commonly fails is this one:
var user = (from u in DatabaseContext.Current.Users
where u.UserName == username
select u).FirstOrDefault();
return user != null;
All I can think of is that deep in the bowels of the EF it is keeping a reference to the DbContext in a cached query plan and then attempting to reuse that context when the query is executed. I've looked at it through reflector and it does seem that some of the internals keep a reference to the ObjectContext.
Is there a way to disable linq query caching? Anyone have any clues?
The other possibility is that a query from a previous call on the Context is leaving the Context in bad state. However, there are no indications of failures that would indicate this.
This is Entity Framework 4.1 using Sql CE (for now, we are soon migrating to a production SQL Server Instance).
Neither of your scenarios should happened. There is no caching you mentioned. There are some possibilities you should check instead:
You are using context after EndRequest or outside of current HttpRequest scope
You are storing entity retrieved from context somewhere in cache or session and using it in other request processing - this can be an issue because entity can keep reference to disposed context and use it for some operations.
There is no automatic LINQ query caching - it is feature planned for upcoming EF release but that feature caches DbCommand instances independent on the context.
You get this exception "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection" - because there is a failed transaction, after that trying to access a data query. Put a try catch and observe the exception. precisely, there is an exception, which is not handled properly.

Entity Framework 4: How expensive is it to create an EntityConnection?

How expensive is it to create an EF4 EntityConnection? I am creating an EF4 desktop app with SQL Compact, and the user will be able to open database files using a File Open dialog. My code then builds an EntityConnection, like this:
// Configure a SQL CE connection string
var sqlCompactConnectionString = string.Format("Data Source={0}", filePath);
// Create an Entity Connection String Builder
var builder = new EntityConnectionStringBuilder();
// Configure Builder
builder.Metadata = string.Format("res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl", m_EdmName);
builder.Provider = "System.Data.SqlServerCe.4.0";
builder.ProviderConnectionString = sqlCompactConnectionString;
var edmConnectionString = builder.ToString();
// Create an EDM connection
var edmConnection = new EntityConnection(edmConnectionString);
I have an ObjectContextFactory class that creates object contexts for Repository classes as needed.
So, here's my question: Is it better practice to build the EntityConnection once, when I initialize the factory, or should the factory build a new connection each time it creates an object context? Thanks for your help.
The overhead in EF4 is from all I know minimal - please verify here - basically it comes down to opening a new database connection and even that cost is small if the provider supports connection pooling (which SQL server does).
Metadata from MetadataWorkspace is is cached globally so this will not decrease performance (that probably wasn't true in 2009 when the blog post linked to in the other post was posted).
Also connection strings from the config file (the other performance problem indicated in that blog post) are all cached in memory, so I can't see how this can negatively impact performance either.
I would definitely use a new entity connection for each unit of work.
Take a look at this blog post. It seems that creating a new EntityConnection for each context is an expensive operation and the source of some major performance problems. The root of these performance issues (in your case) is the creation of the connection metadata. The other performance hit mentioned in the article (getting the connection string frmo config) would not apply to you, as you are supplying your own connection string. In my opinion, you should create a single EntityConnection.
One thing to keep in mind is that according to the documentation, EntityConnection is not guaranteed to be thread safe. If you are going to be accessing these connections from different threads then you will run into problems, and the safest way to solve this would be to not reuse the EntityConnection.

How to create a static UnitOfWork for entity framework 4?

Considering this class
public class XQueries
{
public IQueryable Query1()
{
using (XEntities context = new XEntities())
{
return something;
}
}
public IQueryable Query2()
{
using (XEntities context = new XEntities())
{
return somethingElse;
}
}
}
Is a connection to the database created for every (XEntities context = new XEntities()) {...} ? If so what is the correct way to create a static UnitOfWork class so that only 1 connection to exist?
You can't create a static unit of work, because by definition a unit of work is a short lived object. Because the EF ObjectContext is designed around the unit of work pattern it is a bad idea to have a single ObjectContext instance during the life time of the application. There are several reasons for this.
First of all, the ObjectContext class is not thread-safe. This means that during the unit of work of one user (in a web app for instance), another user can commit his unit of work. When they share the same ObjectContext, it means that in that situation just half of the changes are persisted and changes are not transactional. When you are lucky the ObjectContext fails and throws an exception. When you are unlucky, you corrupt the ObjectContext and safe and load crap from and to your database and find out when your application is running in production (of course, during testing and staging everything always seems to work).
Second, the ObjectContext has a caching mechanism that is designed for it to be short lived. When an entity is retrieved from the database it stays in the ObjectContext’s cache until that instance is garbage collected. When you keep that instance alive for a long period of time, entities get stale. Especially if that particular ObjectContext instance is not the only one writing to that database.
The Entity Framework opens connections only when required, for example to execute a query or to call SaveChanges, and then closes the connection when the operation is complete.
From Martin Fowler’s book Patterns of Enterprise Application Architecture in respect to Unit Of Work.
When you're pulling data in and out of
a database, it's important to keep
track of what you've changed;
otherwise, that data won't be written
back into the database. Similarly you
have to insert new objects you create
and remove any objects you delete.
You can change the database with each
change to your object model, but this
can lead to lots of very small
database calls, which ends up being
very slow. Furthermore it requires you
to have a transaction open for the
whole interaction, which is
impractical if you have a business
transaction that spans multiple
requests. The situation is even worse
if you need to keep track of the
objects you've read so you can avoid
inconsistent reads.
A Unit of Work keeps track of
everything you do during a business
transaction that can affect the
database. When you're done, it figures
out everything that needs to be done
to alter the database as a result of
your work.
Whenever I use Entity Framework for a clients (which I'd admit is rare) the ObjectContext object is the Unit Of Work implementation for the system. That is the ObjectContext will somewhat meet the three statements above. Rather than concentrating too much on the absolutely correct definition using the ObjectContext makes things a little easier for you.
Do some research on DI/IoC and Repository patterns this will give you more flexibility in handling your problem.