C#实体框架:使用MVVM的单例上下文模式

时间:2016-04-28 21:07:30

标签: c# wpf entity-framework mvvm

我使用Entity Framework构建了一个WPF应用程序。我的数据存储由分层数据组成(一个项目,具有多个不同的子实体)。

到目前为止,我一直在为我的上下文使用单例模式,因为这允许我在我的UI中有一个全局导航树(当用户选择扩展特定父项以显示其子项时,它会延迟加载)。到目前为止,这一直很好用,但我现在遇到了可怕的例外:

A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.

据我所知,由于某些实体正在执行某些操作,并且同时发出加载其他实体的请求,所以我都看到了这个异常。所有这些都来自同一个单例上下文。

我进一步明白,最好将上下文保持为尽可能短暂。但是,如果我希望用户能够一次看到整个项目并对某些实体进行更改,那么这将如何成为可能呢?我完全不知道如何使用短暂的上下文来安装这个全局导航树(因为我一直遇到'上下文已被处置'问题)。

我是否应该围绕上下文实现一些锁定机制,或者更糟糕的是,在从上下文请求它之前,让这个锁定机制检查每个属性?这种情况的推荐最佳做法是什么?

1 个答案:

答案 0 :(得分:1)

正确,DbContext个实例很便宜(它们只是池化数据库连接的包装)。

如果要在持久性操作之间维护实体,则可以将实体分离并重新附加到新的DbContext实例:

请参阅https://msdn.microsoft.com/en-us/data/jj592676.aspx

FooEntity fromPreviousContext = ...

using (DbContext context = new DbContext()) 
{ 
    context.Foos.Attach( fromPreviousContext ); 
    context.SaveChanges(); 
}

附注:通常,Singleton模式被许多人视为反模式,因为它很容易被滥用,特别是当单个实例被用于存储上下文数据时 - 它变得只是稍微多一点>礼貌处理全局变量。您可能想要考虑上下文模式(与DbContext无关)。