我正在使用 WPF 进行项目,使用本地数据库(通过 SQL Express )和实体框架作为 ORM
我想将 ViewModels 实现为查看类。有点 1对1 关系,我听说这是实现 MVVM 的好方法(如果你不同意,请分享为什么 )。我的愿景是每个 ViewModel 都为 View 提供服务(即从 Model 层提供的数据库中共享一些数据)。
所以每个 View 都有 ViewModel ,这是一种仆人。 ;)
在实现这个概念的过程中,我遇到了这个问题...让我们假设至少2个 ViewModels 想要获取存储在数据库中的所有客户的最新列表。
在这种情况下我该怎么办?我必须将此代码添加到所有这些 ViewModels (针对DRY):
public ObservableCollection<Customer> Customers;
private ObservableCollection<Customer> GetAllCustomers()
{
var oc = new ObservableCollection<Customer>();
using (var db = new MyDbContext())
{
var query = from b in db.Customers
orderby b.Surname
select b;
foreach (var customer in query)
{
oc.Add(customer);
}
}
return oc;
}
或(或者)我会使用与上面编写的相同的代码制作一些静态FooClass
,但会将其作为 static 。它不是很聪明,因为这样的FooClass
会在一段时间后成为一大堆混乱。
我找不到任何更聪明的解决方案。我相信你知道我应该如何巧妙地编写代码。所以请帮助我。我应该如何为许多 ViewModels 提供相同的功能?
答案 0 :(得分:1)
您应该将使用代码中的数据访问抽象到允许特定数据访问和/或间接访问的某个层中。一个简单的细分是获取您拥有的自定义查询,将它们放在对象中并在不同的视图模型中引用该对象。
下面是一个过于简单的示例,留下了改进的空间,但是应该给出一个大致的想法,不确定viewmodel方法的实用性如下,但再次提供了所述代码的示例。
public class DataAccess {
public IEnumerable<Customer> GetCustomers() {
using (var db = new MyDbContext())
{
var query = from b in db.Customers
orderby b.Surname
select b;
return query.ToList();
}
}
}
...
private ObservableCollection<Customer> GetAllCustomers()
{
var customers = new DataAccess().GetCustomers();
return new ObservableCollection<Customer>(customers);
}
除了这个例子,您可能希望将DataAccess
拆分为处理特定数据集的聚合根类,并且可以处理客户端传递的查询条件,还有其他考虑因素,例如不允许消费者也可以使用数据实体,而是使用特定业务逻辑的DTO或域对象和层。它的长短是我不建议直接从您的视图模型访问您的EF数据上下文,除非这只是玩具/原型代码。