每组操作可重用的ObjectContext或新的ObjectContext?

时间:2009-08-09 18:24:12

标签: c# linq-to-entities data-access-layer objectcontext

我是实体框架的新手,我刚开始在空闲时间玩它。我遇到的一个主要问题是如何处理ObjectContexts。

通常首选/推荐这些:

:此

public class DataAccess{

    MyDbContext m_Context;

    public DataAccess(){
        m_Context = new MyDbContext();        
    }

    public IEnumerable<SomeItem> GetSomeItems(){
        return m_Context.SomeItems;
    }

    public void DeleteSomeItem(SomeItem item){
        m_Context.DeleteObject(item);
        m_Context.SaveChanges();
    }
}

还是这个?

public class DataAccess{

    public DataAccess(){ }

    public IEnumerable<SomeItem> GetSomeItems(){
        MyDbContext context = new DbContext();
        return context.SomeItems;
    }

    public void DeleteSomeItem(SomeItem item){
        MyDbContext context = new DbContext();
        context.DeleteObject(item);
        context.SaveChanges();
    }
}

4 个答案:

答案 0 :(得分:6)

ObjectContext意味着“工作单元”。

基本上这意味着对于每个“操作”(例如:每个网页请求),应该有一个新的ObjectContext实例。在该操作中,应该重用相同的ObjectContext。

当您考虑这一点时,这是有道理的,因为事务和更改提交都与ObjectContext实例绑定。

如果您不是在编写Web应用程序,而是编写WPF或Windows窗体应用程序,那么它会变得有点复杂,因为您没有网页的紧密“请求”范围 - 加载给你,但你明白了。

PS:在您的任何一个示例中,ObjectContext的生命周期将是全局的或瞬态的。在这两种情况下,它不应该存在于DataAccess类中 - 它应该作为依赖项传递

答案 1 :(得分:1)

如果你对长时间运行进程运行批量查询保持相同的上下文,linq-to-sql(我没有针对linq对实体进行测试,但我想这是同样的问题)得到非常慢(在1000次简单查询后每秒1次查询)。定期更新背景可以解决这个问题,而且费用不高。

上下文会跟踪你在其上执行的每个查询,所以如果它没有以某种方式重置,它会变得非常胖......其他问题就是它所占用的内存。

因此,它主要取决于您的应用程序的工作方式,以及您是否定期新建DataAccess实例,或者您是否一直保持相同。 希望这会有所帮助。

斯特凡

答案 2 :(得分:0)

只是一个简单的说明 - 这两个代码在底层问题上大致相同。这是我一直在关注的内容,因为你不想继续打开和关闭上下文(参见第二个例子),同时你不确定你是否可以信任Microsoft为你妥善处理上下文。

我做的一件事是创建一个公共基类,它延迟加载Context并实现基类析构函数来处理事物。这适用于类似MVC框架的东西,但不幸的是导致必须将上下文传递到各个层的问题,以便业务对象可以共享调用。

最后,我使用Ninject将一些内容注入到每个图层中并使其跟踪使用情况

答案 3 :(得分:0)

虽然我并不赞成每次需要时总是创建,必须是复杂的对象 - 我也发现Linq to Sql中的DataContexts和EF中的ObjectContexts最好在需要时创建。

这两个都基于您运行它们的模型执行大量静态初始化,这些模型被缓存用于后续调用,因此您将发现上下文的初始启动将比所有后续实例更长。 / p>

您面临的最大障碍是,一旦您从上下文中获取实体,您就不能简单地将其传递回另一个实体进行更新操作,或者重新添加相关实体。在EF中您可以重新附加一个实体回到新的背景。在L2S中,这个过程几乎不可能。