c# - 将 L2S DataContext 传递到 ViewModel 构造函数干净的 MVVM 中吗?

标签 c# wpf linq-to-sql mvvm

在我的主 Window1.xaml.cs 中,我通过使用 LINQ-to-SQL 模型对象实例化来构建一个 ObservableCollection of ViewModels:

using (var db = Datasource.GetContext())
{
    var customers = from c in db.Customers
                    select c;

    foreach (var customer in customers)
    {
        CustomerCollection.Add(new CustomerModelView(customer));
    }
}  

在每个 ViewModel 的构造函数中,我在内部保存 LINQ-to-SQL 对象并将所有属性从 Model 映射到 ViewModel:

#region ViewModelProperty: Customer
private Customer _customer;
public Customer Customer
{
    get
    {
        return _customer;
    }

    set
    {
        _customer = value;
        OnPropertyChanged("Customer");
    }
}
#endregion

#region ViewModelProperty: FirstName
private string _firstName;
public string FirstName
{
    get
    {
        return _firstName;
    }

    set
    {
        _firstName = value;
        OnPropertyChanged("FirstName");
    }
}
#endregion

...

public CustomerViewModel(Customer customer)
{
    Customer customer;
    FirstName = customer.FirstName;
    ...
}

问题是在我的 ViewModel 中处理事件时,例如在用户更改任何字段并单击 Save 按钮后,我必须重新实例化 LINQ-to-SQL 对象以保存更改,这会产生更多流量当我实际上已经在内部保存了对象时进出数据库:

using (var db = Datasource.GetContext())
{
    var customer = (from c in db.Customers
                 where c.Id == Id
                 select c).SingleOrDefault();

    customer.FirstName = FirstName;
    db.SubmitChanges();
} 

直接的解决方案是在实例化 ViewModel 时也将 LINQ-to-SQL datacontext 对象 传递给 ViewModel,如下所示:

public CustomerViewModel(Customer customer, DataClasses1DataContext db)
{
    Customer = customer;
    Db = db;

    FirstName = customer.FirstName;
    ...
}

然后在处理诸如 Save 按钮之类的事件时,我可以在 internal Db 上调用 SubmitChanges() 变量而不重新实例化它并再次从数据库中获取数据。

所以我似乎必须要么 (1) 将数据层上下文对象传递到 ViewModel 中,这似乎不是解决此问题的 clean MVVM 方法,要么 (2) 我必须每次我想保存已在 ViewModel 内部保存的模型对象时,重新获取我的 LINQ-to-SQL 对象。

解决这个难题的最干净的 MVVM 方法是什么?

最佳答案

这意味着您的 ViewModel 了解数据层。我认为最好使用对象初始化上下文。这也允许您这样做:

using (var db = Datasource.GetContext())
{
    var customers = from c in db.Customers
                    select new CustomerModelView
                    {
                        Name = c.Name;
                        Address = c.Address;
                    };

    CustomerCollection.AddRange(customers);
}

更新数据库时,您应该能够创建一个新对象,然后使用 db.AttachObject 让上下文知道它。这使您不必为了更改它而不得不从数据库中重新获取它。

关于c# - 将 L2S DataContext 传递到 ViewModel 构造函数干净的 MVVM 中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1963053/

相关文章:

c# - 带有窗口的石头剪刀布游戏

c# - Wpf 控制可见性?

c# - Linq-to-Sql SubmitChanges 不更新字段......为什么?

linq-to-sql - 为什么 LinqPad 创建字段而不是属性?

c# - 如何从使用 LINQ to SQL 的 c# 方法返回匿名类型

c# - 如何判断分部方法没有实现

c# - 如果使用 Entity Framework ,如何简化

c# - 用动态列填充数据网格

c# - 如何将图像嵌入到 RichTextBox 中?

wpf - WPF 应用程序中的 CUDA 和 Direct3D 互操作性