几个月来,我一直在使用 WPF MVVM 和实体框架编写应用程序,我意识到我的代码体系结构开始变得混乱。我似乎无法找到一种方法来将 EF 和 WPF 正确连接在一起,同时保持两层数据的不同和一致。
实体始终是分离的,因为保持它们附加意味着我们必须为整个应用程序保留 DbContext 的单个实例,不建议这样做。
目前,这是我的架构:
- 大多数写入操作都放入从不采用的服务中 实体作为参数,只有它们的 ID。
- 视图模型调用服务,但由于实体未附加,因此视图不会更新
- ViewModels 直接从 DbContext 检索其数据,根据需要显示的内容选择要包含的属性
问题:
- 感觉不对劲。我觉得我没有正确使用 EF,这让我很不高兴。 我
- 最终得到了许多具有未定义属性的实体实例(我不能总是包含所有这些实例,它会消耗太多内存)
- 我的视图模型中有 EF 代码
除了非常基本的教程之外,我似乎也无法在线找到任何适当的 WPF - EF 体系结构示例。
例:
class ViewModel : BaseViewModel
{
private Service _service;
public ViewModel(Service service)
{
LoadEntities();
}
public IList<Entity> Entities { get; set; }
private void LoadEntities()
{
using(var context = new DbContext())
{
Entities = context.Entities
.Include("Reference.Foo")
.ToList();
}
}
private void DeleteEntity(Entity entity)
{
_service.DeleteEntity(entity.Id);
Entities.Remove(entity);
}
}
这是一个非常"大"的问题......而且很难在一个简单的帖子上分析
出来为什么专注于EF?架构对所有人都是一样的。简单地说:实体;数据访问层;商业服务;GUI(视图、视图模型、服务 - 仅使用实体和服务)
你说"目前,这是我的架构"==>对我来说,这3点是错误的。 将实体提供给服务不是问题,将实体附加到视图模型,不要直接在视图模型中调用 DB/EF,而是使用服务
- 程序集.实体
- 装配.商业服务
- Assembly.DAL
- Assembly.GUI
祝你好运
一些提示:
-
使用 IoC 容器来管理所有/大部分依赖项,包括 DbContext。这样,您始终可以更好地测试所有内容。然后,您可以配置这些依赖项的范围(单一实例、瞬态等)。一些流行的选项是autofac,Castle Windsor,ninject或.net内置的ioc容器。
-
查看存储库模式,它将极大地分离所有内容
-
保持视图模型尽可能愚蠢
-
将来自 EF 模型的数据映射到 DTO,不要直接在视图中使用实体
- 研究固体原则