I create a new System.Data.Objects.ObjectContext (my EF model) every time a DAL method is called:
Public void DoSomeDataManipulation()
{
using (MyModel myModel = new MyModel(connectionString))
myModel.AddRecord(someParametersHere);
}
DoSomeDataManipulation() is called frequently (also many other methods). I have tried a static version of myModel but EF produces many concurrency errors on high load.
Currently I'm curious if this approach can lead a Large Object Heap or not and if it is the best practice for calling mapped EF methods.
Using static context is a bad practice - you have found that it doesn't work in concurrent scenario (because context is not thread safe) but it also has other problems.
You should use a new instance of the context for each unit of work. Is adding single record unit of work (business operation / transaction)? In such case you are using it right. If your unit of work is adding multiple records or any other more complicated scenario where you insert / update / delete several entities you should use one context instance for the whole operation.
Using new context for the operation should not cause performance problems. Context internally uses some mapping description which is shared anyway. Problems with large heap can happen but that will not make any difference when using static context.
Large heap can happen due to memory leaks caused most often by POCO proxies (either tracking or lazy loading). If you load entity from the context and then dispose the context without detaching the entity it will still hold reference to the context and context will hold references to all attached entities = if the main entity is still referenced neither object context or anything it references can be garbage collected. In the same time detaching entity will break all relations because there is no "DetachGraph". You can detach entities one-by-one and EF will break navigation properties. I think this is a bug in Entity framework and dynamic proxies.
Related
My context.SaveChanges() contains over 60 lines of error handling catching exceptions such as DbUpdateException or DBEntityValidationException, etc. It is tedious to duplicate that error handling in every SaveChanges throughout my various solutions. Is there some way to pass the context as a variable type to a single library routine? For example
public bool mySaveChanges(*Entities* anyDbContext)
{
anyDbContext.SaveChanges();
}
where the type 'Entities' would be replaced with some language construct meaning any Entities and not a specific Entities.edmx.
P.S. Yes, I am aware that EF is not thread safe but there is only one user running this code so not concerned about that aspect.
I've run into the same question repeatedly whenever using a new DI framework... how do you run massively-parallel operation kicked off from an HttpRequest where each thread needs its own unique copy of the dependencies? In my case, I'm using Ninject.
The specific case I always run into is a CPU-intensive report, using Parallel.ForEach, that needs to use an Entity Framework DbContext; the EF context must be unique to the thread, but outside of these special reports the EF context it must be InRequestScope.
How do you achieve this with Ninject? Preferably allow disposing the EF context with each task on the Parallel.ForEach, since the data loaded with the context would just stay in the context and consume memory.
Note that this report is big enough to warrant Parallel.ForEach but small enough that it can run synchronously on a web request and not timeout the browser (<60 seconds). Maybe I'm weird, but I run into this need a lot.
The solution has several different moving parts that, IMO, aren't terribly well-documented parts of Ninject. The upside is that after implementing something like this, you should start feeling comfortable with Ninject in a hurry!
First, you need to change the scope for your objects so they use the HttpContext if it exists, and if not, use the current thread as a fallback. There is no documentation for this, but there is a DefaultScopeCallback that was added to the settings a while back. Set that property to your own scope callback which uses the same code in the Ninject.Web.Common source to get the HttpContext, but then use "?? Thread.CurrentThread" as the fallback. Do that in the CreateKernel code that should have been created automatically when you installed the NuGet package.
(I have substituted the StandardScopeCallbacks.Thread(ctx) where I used to have Thread.CurrentThread, since the former could conceivably change at some point. Currently those two are identical in what they do.)
private static IKernel CreateKernel()
{
var settings = new NinjectSettings{ DefaultScopeCallback = DefaultScopeCallback };
var kernel = new StandardKernel(settings);
// The rest of the default implementation of CreateKernel left out for brevity
}
private static Object DefaultScopeCallback(Ninject.Activation.IContext ctx)
{
var scope = ctx.Kernel.Components.GetAll<INinjectHttpApplicationPlugin>()
.Select(c => c.GetRequestScope(ctx)).FirstOrDefault(s => s != null);
return scope ?? Ninject.Infrastructure.StandardScopeCallbacks.Thread(ctx);
}
Also, don't forget that the Kernel needs to be set aside as a static object for access later. You don't want to new-up a new Kernel every time you need it; I make mine accessible via "MyConfig.ObjectFactory". While this is a code smell of the service locator anti-pattern, we're going to great lengths here to avoid the anti-pattern as much as possible.
Second, according to the commit description, the DefaultScopeCallback only affects explicit bindings with no explicit scope. So if, like me, you were depending on a bunch of implicit bindings that you hadn't added, you now need to configure them:
kernel.Bind(i => i.From(Assembly.GetExecutingAssembly(), Assembly.GetAssembly(typeof(Bll.MyConfig)))
.SelectAllClasses()
.BindToSelf());
If you don't like doing the above, there's another way of setting the default scope for all implicit bindings that is arguably more elegant. Changing default object scope with Ninject 2.2
Third, if you'd like to clear all cached objects from the scope at the end of each Parallel operation so that memory usage doesn't skyrocket due to EF caching or whatnot, here's how clear the Ninject cache scoped to the current thread:
Parallel.ForEach(myList, i =>
{
var threadDb = MyConfig.ObjectFactory.Get<MyContext>();
CreateModelsForItem(i, threadDb);
MyConfig.ObjectFactory.Components.Get<Ninject.Activation.Caching.ICache>().Clear(Thread.CurrentThread);
});
Note that I did some testing without that Clear line at the end, and it seemed like the EF Context was getting re-used even if that HttpRequest finished and I generated the report several more times. This was not what I wanted, so the Clear operation was important. Really, the behavior I want is closer to InCallScope, but trying to get InRequestScope with InCallScope as a fallback is a can of worms I'll open on another day.
I have some "caching" objects in my application, that get a IRepository (custom repository pattern contract) by dependency injection (Ninject). Those objects only uses the repository once, but they have a Refresh function that forces the owner to refresh itself. They are singletons, are created only once, and a ManualResetEvent ensures that all requests are blocked till it is loaded.
The IRepositories are EF CodeFirst based, so is it OK just to simply ensure the connection is closed and keep the reference to the DbContext there forever?
I have disabled the proxies and the lazy loading, so... is OK to have long references from the root of the caching object to hundreds of these cached POCO entities?
Cheers.
We reference to comments from Julie Lerman,
http://msdn.microsoft.com/en-us/magazine/ee532098.aspx?sdmr=JulieLerman
the recommendation is to have several/many smaller contexts and in the case of web scenarios create a new context each call.
Although she writes about Second-Level Caching in the Entity Framework and AppFabric.
Over time, the context would be contain many objects and the performance would decline accordingly.
I think this site has some good tips on EF performance.
eg generated views.
http://msdn.microsoft.com/en-us/data/hh949853
my personal recommendation, that I cant claim is best practice, but from someone who is concerned about performance, is that small bounded context each call is a solid long term compromise.
Use generated views to keep the initial load time as small as possible.
you could potentially manage a permanent DBContext in such a way as to drop unused objects from the context. Or use a caching library with events to do so. Not a small task.
I would be interested in the solution you finally select. please post.
Finally the best solution I found is to create a new kind of wrapper:
public class Generator<T> where T : IDisposable
{
readonly Func<T> _generate;
public Generator(Func<T> generate)
{
_generate= generate;
}
public T Generate()
{
return _generate();
}
}
And create a binding more or less this way:
// Dependency Injection bindings declaration section
DI.Bind<Generator<IRepository>>()
.To(()=> new Generator<IRepository>(()=> DI.Get<IRepository>()));
Therefore, in long lived objects that needs to just create and destroy the element, I can ask for a Generator<IRepository> service, rather than IRepository. Therefore, every time I need to refresh, I would just create a new IRepository, without knowing how it is build under the hood:
using (var repository = repositoryGenerator.Generate())
{
repository.DoStuff();
}
It works like a charm so far.
Actually, I have added this feature to my DI framework. I can now bind IAnything and later on request for Generator, and the framework will give me the fully ready object using this technique How to create a Func<> delegate programmatically
Cheers.
I have an application using the Entity Framework code first. My setup is that I have a core service which all other services inherit from. The core service contains the following code:
public static DatabaseContext db = new DatabaseContext();
public CoreService()
{
db.Database.Initialize(force: false);
}
Then, another class will inherit from CoreService and when it needs to query the database will just run some code such as:
db.Products.Where(blah => blah.IsEnabled);
However, I seem to be getting conflicting stories as to which is best.
Some people advise NOT to do what I'm doing.
Other people say that you should define the context for each class (rather than use a base class to instantiate it)
Others say that for EVERY database call, I should wrap it in a using block. I've never seen this in any of the examples from Microsoft.
Can anyone clarify?
I'm currently at a point where refactoring is possible and quite quick, so I'd like some general advice if possible.
You should wrap one context per web request. Hold it open for as long as you need it, then get rid of it when you are finished. That's what the using is for.
Do NOT wrap up your context in a Singleton. That is not a good idea.
If you are working with clients like WinForms then I think you would wrap the context around each form but that's not my area.
Also, make sure you know when you are going to be actually executing against your datasource so you don't end up enumerating multiple times when you might only need to do so once to work with the results.
Lastly, you have seen this practice from MS as lots of the ADO stuff supports being wrapped in a using but hardly anyone realises this.
I suggest to use design principle "prefer composition over inheritance".
You can have the reference of the database context in your base class.
Implement a singleton for getting the DataContext and assign the datacontext to this reference.
The conflicts you get are not related to sharing the context between classes but are caused by the static declaration of your context. If you make the context an instance field of your service class, so that every service instance gets its own context, there should be no issues.
The using pattern you mention is not required but instead you should make sure that context.Dispose() is called at the service disposal.
I'm using Entity Framework in my project, and I have the problem that, once I pass my entities to a View (keep in mind that these entities have lazy-initialized objects along the lines of: Products.Owner, where owner is an object that is lazily initialized) I get a run-time exception telling me that the ObjectContext is out of scope.
Now this makes sense since I am getting the entities from a Service with a using (.... entities...) { .... } statement, which means it is disposed when the result is returned.
How would I get around this and have an Object Context that is alive from start to end. Thanks.
One option is to associate the repository with the Request, and have the Repository implement IDisposable, and have the Dispose method dispose of the contained ObjectContext, rather than using the more familiar using pattern inside your controller actions.