【发布时间】:2010-07-29 20:27:34
【问题描述】:
我刚刚开始使用带有存储库模式的 EF4。我必须在每次使用上下文后调用 dispose 方法,或者在 using 块中包装代码。我可以使用 ObjectContext 而不在我编写的每个方法中都这样做吗?或者在存储库中是否有更好的方法来处理它。
此外,我也不想将 ObjectContext 从 UI 传递到存储库。
【问题讨论】:
标签: entity-framework
我刚刚开始使用带有存储库模式的 EF4。我必须在每次使用上下文后调用 dispose 方法,或者在 using 块中包装代码。我可以使用 ObjectContext 而不在我编写的每个方法中都这样做吗?或者在存储库中是否有更好的方法来处理它。
此外,我也不想将 ObjectContext 从 UI 传递到存储库。
【问题讨论】:
标签: entity-framework
要在不依赖注入的情况下尽可能有效地作为资源执行此操作,我建议您为对象上下文实现一个私有的延迟加载属性。
private ObjectContext _context;
private ObjectContext Context
{ get
{
return _context ?? (_context = new ObjectContext());
}
}
接下来,让您的存储库实现 IDisposable 并在您的 dispose 方法中处理对象上下文:
public Repository : IDisposable
{
...
public void Dispose()
{
_context.Dispose();
}
}
然后,您只需在所有方法中使用该属性,并将您的存储库的使用情况包装在 using 语句中。
为了减少数据库的流量,您还可以将保存因素分解到存储库上的单独方法中,该方法只是将调用转发到对象上下文。这样,您可以更好地控制何时数据保存在 UI 层中,即使您不控制如何。这意味着你可以这样做
using (var repo = new Repository())
{
repo.AddSomeStuff("this", "is", true);
repo.ChangeSomethingElse("yes, please");
repo.Save();
}
从 EF 到数据库只会有一次调用。另一方面,如果你这样做了
using (var repo = new Repository())
{
repo.AddSomeStuff("this", "is", true);
repo.ChangeSomethingElse("yes, please");
}
什么都没有发生,这可能会令人困惑。
【讨论】:
使用对象上下文的一般模式是:
public BusinessObject GetSomething(){
using (MyObjectContext context = new MyObjectContext()){
//..do fun stuff
}
}
希望这是您使用的模式。当您可以只使用“using”语句时,调用 dispose 似乎有点矫枉过正。
另一个选项是,如果您要在一个流中执行多个数据库查询。我见过一种模式,您可以在线程中重用相同的上下文。人们基本上实现了基于线程的单例模式并传递上下文。这样做的好处是不必重建上下文,以及一些内存缓存。缺点是您可能会遇到并发问题。有人更新了您在 EF 内部缓存的内容。
我猜第二种情况并不适用,因为听起来你正在编写一个小应用程序。 (该声明基于您的 cmets 关于从 UI 传递上下文的声明......这将吓到任何优秀的代码架构师)。
如果您对基于线程的单例感兴趣。首先了解Singleton 模式,然后查看blog 关于“DataContext”线程。您必须将“DataContext”类型更改为 ObjectContext 类,但它会起作用。
编辑
我会说我忽略了一个明显的解决方案,那就是下面 ;)。只需使用基于属性的对象上下文并在 using 语句中播放您的存储库。它与上面的使用示例相同,但您将实现 IDisoposable。
【讨论】: