实体框架ObjectContext重用

时间:2010-04-27 19:04:19

标签: asp.net entity-framework

我现在正在学习EF并且对ObjectContext有疑问:

当我访问数据库时,是否应该为每个查询(函数)创建ObjectContext实例?

或者最好创建一次(单例)并重复使用它?

在EF之前我使用企业库数据访问块并为DataAccess函数创建了dataacess实例...

6 个答案:

答案 0 :(得分:15)

我认为最常见的方法是根据请求使用它。在开头创建它,做你需要的(大多数时候这些是需要常见ObjectContext的操作),最后处理。大多数DI框架都支持这种情况,但您也可以使用HttpModule创建上下文并将其放在HttpContext.Current.Items中。这是一个简单的例子:

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;
    }
}

答案 1 :(得分:14)

绝对适用于每个查询。它是一个轻量级的对象,因此每次需要时都不会产生太多成本。

此外,保持ObjectContext活动的时间越长,在对其运行查询时它将包含的缓存对象就越多。这可能会导致内存问题。因此,将ObjectContext作为单例是一个特别糟糕的主意。在使用您的应用程序时,您在单例ObjectContext中加载越来越多的实体,直到最终您将整个数据库放在内存中(除非您在不再需要实体时分离实体)。

然后存在可维护性问题。有一天,你试图追踪一个错误,但无法弄清楚导致它的数据加载位置。

答案 2 :(得分:1)

不要使用单身人士...使用你的应用程序的每个人都会分享这一点,当对象上下文跟踪实体时,会发生各种疯狂的事情。

我会将其添加为私人会员

答案 3 :(得分:1)

就像卢克所说,这个问题在SO上被多次提出过。

对于Web应用程序,每个请求周期似乎效果最好。单身人士绝对是个坏主意。

每个请求都运行良好,因为一个网页有一个用户,也许属于该用户的一些项目,也许是该用户的一些消息。你想要相同的ObjectContext,所以你可以去User.Messages来获取它们,也许将一些消息标记为已读,也许添加一个Project然后在页面循环完成时提交或放弃整个对象图。

答案 4 :(得分:0)

这里迟到了7个月。我目前正在我的应用程序中解决这个问题,我倾向于@LukLed解决方案,在我的HttpRequest期间创建一个单独的ObjectContext。对于我的架构,我有几个控件用于构建页面,这些控件都有自己的数据关注点,从EF层提取只读数据。每个人创建和使用自己的ObjectContext似乎都是浪费。此外,在某些情况下,一个控件可能会将数据拉入Context,而其他控件可能会重复使用。例如,在我的母版页中,页面顶部的标题包含用户信息,可以由页面上的其他控件重复使用。

我唯一担心的是,我可能会将实体拉入影响其他控件查询的上下文中。我还没有看到,但不知道我是否在寻找麻烦。我猜我们会看到的!

答案 5 :(得分:0)

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);
        }
    }