[EDITED]
我正在寻找一种在WPF(MVVM)应用程序中实现Linq To Entities的方法,并使每个View(或ViewModel)负责分别管理其底层实体。
以下是一个简单结构的例子以及我想要实现的目标:
[客户](1..1)< ----> (0 .. *)[订单](0 .. *)< - [ OrderLine ] - > (1 .. *)[产品]
第一个视图显示客户列表
第二个视图显示客户的详细信息及其订单列表
第三个视图显示订单的详细信息和订单行列表
第四个视图显示产品的详细信息
根据Microsoft的建议,每个视图实例(或viewModel实例)(https://msdn.microsoft.com/en-us/data/jj729737.aspx)必须有一个DbContext实例。
上述方案当然非常简化。在实际应用中,我们将拥有更多的实体和视图。另外,它们可能是打开视图的不同流程,这使得在打开新视图时很难预先知道哪些实体已从数据库加载。
仍然有一个原则:视图(或相应的ViewModel)应该负责更新它显示的实体集,而不要求DbContext更新另一个视图处理的实体。
问题
productView的DbContext应该能够将相关产品的更改推送到数据库。但是,如果先前已加载产品(即通过与orderLinesView关联的DbContext),则不应从数据库加载产品。问题在于,正如我所理解的那样,DbContext封装了一个事务,这使得我认为很难负责保存它本身没有加载的实体。如何解决这个问题?
很明显,每个视图实例都必须有一个DbContext实例,以便SaveChanges()只处理当前视图的数据。目前尚不清楚的是天气我应该有几个继承DbContext的类或一个代表应用程序DbContext的类。
是否需要添加DbSet<>我们想要更新的每个权利类型的DbContext上的属性?随着应用程序随新实体的增长,似乎DbContext需要随时更改。另外,这意味着viewModels中的重复代码指出哪个DbSet<>应该加载等 拥有一个可以接收一组实体进行更新的机制(1)(无论其类型),以及允许选择一组实体传递给机制的另一种机制(2)不是更有效(1) )?第二种机制可以是手动(对于灵活方案)或自动(通过查看ViewModel中列出的所有实体)。
如果我想将数据库访问机制放在Web服务中,我该如何继续单独管理每个视图的基础实体?在这种情况下,应该在何处以及如何实例化DbContexts?
我期待您提出的任何建议。
答案 0 :(得分:0)
您可能正在实施类似Unit of Work and Repository Pattern
的内容通过这种方式,您可以将对数据库执行的更改作为工作(您的案例中的窗口)的一部分与其他工作分开。如果对所有这些使用相同的上下文,那将会很复杂。
编辑:试着回答你的一些问题:
1)只要下一个视图不会改变其他视图中的实体,您就可以将DTO传递给它以获取它们的逻辑。但是,如果您登录的数据发生了变化,这可能会导致一些并发问题。没有简单的方法可以解决这个问题,而无需一次性保存所有相关的实体。您可以尝试创建自己的缓存并使用它而不是在这些情况下查询DbContext,但这又可能是多个用户的问题。
2和3)看看我上面提到的工作单元和存储库模式。这应该是一个很好的包装器,以避免重复代码。
4)对于Web服务,您应该为每个请求创建一个DbContext,否则您可能会再次遇到并发问题。在这里拥有缓存也可以提高性能。