【问题标题】:Need the same sort of data fetched from databse in many ViewModels在许多 ViewModel 中需要从数据库中获取相同类型的数据
【发布时间】:2012-11-05 19:00:33
【问题描述】:

我正在 WPF 中开发项目,使用本地数据库(通过 SQL Express)和 Entity Framework 作为 ORM .

我想实现与 View 类一样多的 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 提供相同的功能?

【问题讨论】:

    标签: entity-framework mvvm viewmodel dry


    【解决方案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 数据上下文,除非这只是玩具/原型代码。

    【讨论】:

    • 所以每次在我的应用程序中打开一个新的(子)窗口时,我都需要创建新的DataAccess 对象。这是个好主意吗?也许静态类会更好?我知道将类和方法设为静态是出现问题的线索,但在这种情况下,我会说在每个打开的窗口上调用 new DataAccess() 会更糟。
    • @patryk.beza 正确我不一定建议在每次调用时都创建一个新对象,但老实说,只要您正确处理依赖项,这是一项非常轻量级的活动。当我说该示例有改进的余地时,这是考虑因素之一,我想您会希望针对您的特定用例进行定制。有很多选择,并且都有其优点和缺点。要点是将数据访问逻辑从视图模型中抽象出来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 2018-05-24
    • 2019-10-24
    • 2016-10-18
    • 2019-02-11
    相关资源
    最近更新 更多