每组操作的可重用 ObjectContext 还是新的 ObjectContext?
Posted
技术标签:
【中文标题】每组操作的可重用 ObjectContext 还是新的 ObjectContext?【英文标题】:Reuseable ObjectContext or new ObjectContext for each set of operations? 【发布时间】:2010-11-18 02:59:45 【问题描述】:我是实体框架的新手,我刚开始在空闲时间玩弄它。我遇到的主要问题之一是关于如何处理 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();
【问题讨论】:
与***.com/questions/1072391/…有些关系 还有这个...***.com/questions/226127虽然讨论的是Linq2Sql,但同样适用。 【参考方案1】:ObjectContext 是“工作单元”。
基本上这意味着对于每个“操作”(例如:每个网页请求)都应该有一个新的 ObjectContext 实例。在该操作中,应该重复使用相同的 ObjectContext。
仔细想想,这是有道理的,因为事务和更改提交都与 ObjectContext 实例相关联。
如果您不是在编写 Web 应用程序,而是在编写 WPF 或 Windows 窗体应用程序,它会变得有点复杂,因为您没有网页那样的“请求”范围- load 给了你,但你明白了。
PS:在您的任何一个示例中,ObjectContext 的生命周期都将是全局的或瞬态的。在这两种情况下,它都不应该存在于 DataAccess 类中 - 它应该作为依赖项传入
【讨论】:
【参考方案2】:如果您为 long-running 进程对它运行 lots 查询 保持相同的上下文,linq-to-sql(我没有针对 linq to entity 进行测试,但我想这是同样的问题)变得非常慢(大约 1000 个简单查询后每秒 1 个查询)。定期更新上下文可以解决这个问题,而且不会花费太多。
发生的情况是上下文会跟踪您对其执行的每个查询,所以如果它没有以某种方式重置,它会变得非常胖......其他问题是它占用的内存。
因此,这主要取决于您的应用程序的工作方式,以及您是否定期更新 DataAccess 实例,或者是否一直保持不变。 希望这会有所帮助。
史蒂芬
【讨论】:
【参考方案3】:只是一个简短的说明 - 两个代码片段在其潜在问题上大致相同。这是我一直在研究的内容,因为您不想在不确定是否可以信任 Microsoft 为您正确处理上下文的同时继续打开和关闭上下文(参见第二个示例)。
我所做的其中一件事是创建一个公共基类,该基类延迟加载上下文并实现基类 destruct-er 来处理事物。这对于像 MVC 框架这样的东西很有效,但不幸的是导致了必须将上下文传递到各个层以便业务对象可以共享调用的问题。
最后我使用 Ninject 将这个依赖注入到每一层并让它跟踪使用情况
【讨论】:
微软建议不要使用长时间运行的 DataContexts 或 ObjectContexts。它会降低性能并使对象跟踪复杂化。【参考方案4】:虽然我不赞成每次需要时总是创建复杂的对象,但我也发现 Linq to Sql 中的 DataContexts 和 EF 中的 ObjectContexts 最好在需要时创建。
p>这两者都基于您运行它们的模型执行大量静态初始化,这些模型被缓存以供后续调用,因此您会发现上下文的初始启动将比所有后续实例化更长。
您面临的最大障碍是,一旦您从上下文中获取了一个实体,您就不能简单地将它传递回另一个实体以执行更新操作,或者重新添加相关实体。在 EF 中,您可以重新附加一个实体回到一个新的上下文。在 L2S 中,这个过程几乎是不可能的。
【讨论】:
因此——我总是在 datacontext/objectcontext 周围有一个 using 语句,并将所有数据操作推入其中;我的上下文总是尽可能短暂。以上是关于每组操作的可重用 ObjectContext 还是新的 ObjectContext?的主要内容,如果未能解决你的问题,请参考以下文章