开发者

Entity Framework ObjectContext re-usage

I'm learning EF now and have a question regarding the O开发者_如何学运维bjectContext:

Should I create instance of ObjectContext for every query (function) when I access the database?

Or it's better to create it once (singleton) and reuse it?

Before EF I was using enterprise library data access block and created instance of dataacess for DataAccess function...


I think the most common way is to use it per request. Create it at the beginning, do what you need (most of the time these are operation that require common ObjectContext), dispose at the end. Most of DI frameworks support this scenario, but you can also use HttpModule to create context and place it in HttpContext.Current.Items. That is simple example:

public class MyEntitiesHttpModule : IHttpModule
{
    public void Init(HttpApplication application)
    {
        application.BeginRequest += ApplicationBeginRequest;
        application.EndRequest += ApplicationEndRequest;
    }

    private void ApplicationEndRequest(object sender, EventArgs e)
    {
        if (HttpContext.Current.Items[@"MyEntities"] != null)
            ((MyEntities)HttpContext.Current.Items[@"MyEntities"]).Dispose();
    }

    private static void ApplicationBeginRequest(Object source, EventArgs e)
    {
        var context = new MyEntities();
        HttpContext.Current.Items[@"MyEntities"] = context;
    }
}


Definitely for every query. It's a lightweight object so there's not much cost incurred creating one each time you need it.

Besides, the longer you keep an ObjectContext alive, the more cached objects it will contain as you run queries against it. This may cause memory problems. Therefore, having the ObjectContext as a singleton is a particularly bad idea. As your application is being used you load more and more entities in the singleton ObjectContext until finally you have the entire database in memory (unless you detach entities when you no longer need them).

And then there's a maintainability issue. One day you try to track down a bug but can't figure out where the data was loaded that caused it.


Don't use a singleton.. everyone using your app will share that and all sorts of crazy things will happen when that object context is tracking entities.

I would add it as a private member


Like Luke says this question has been asked numerous times on SO.

For a web application, per request cycle seems to work best. Singleton is definitely a bad idea.

Per request works well because one web page has a User, maybe some Projects belonging to that user, maybe some Messages for that user. You want the same ObjectContext so you can go User.Messages to get them, maybe mark some messages as read, maybe add a Project and then either commit or abandon the whole object graph at the completion of the page cycle.


Late post here by 7 months. I am currently tackling this question in my app and I'm leaning towards the @LukLed solution by creating a singleton ObjectContext for the duration of my HttpRequest. For my architecture, I have several controls that go into building a page and these controls all have their own data concerns that pull read-only data from the EF layer. It seems wasteful for them to each create and use their own ObjectContext's. Besides, there are a few situations where one control may pull data into the Context that could be reused by other controls. For instance, in my masterpage, my header at the top of the page has user information that can be reused by the other controls on the page.

My only worry is that I may pull entities into the context that will affect the queries of other controls. I haven't seen that yet but don't know if I'm asking for trouble. I guess we'll see!


public class DBModel {

        private const string _PREFIX = "ObjectContext";

        // DBModel.GetInstance<EntityObject>();
        public static ObjectContext GetInstance<T>() {
            var key = CreateKey<T>();
            HttpContext.Current.Items[key] = HttpContext.Current.Items[key] ?? Activator.CreateInstance<T>();
            return HttpContext.Current.Items[key] as ObjectContext;
        }

        private static string CreateKey<T>() {
            return string.Format("{0}_{1}", _PREFIX, typeof(T).Name);
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜