将L2S DataContext传递给ViewModel构造函数清理MVVM?

时间:2009-12-26 10:18:23

标签: c# wpf linq-to-sql mvvm

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

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按钮)时,我可以在内部 SubmitChanges()变量上调用Db,而无需重新验证它并获取来自数据库的数据。

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

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

1 个答案:

答案 0 :(得分:2)

这意味着您的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使上下文知道它。这样您就不必再从DB中重新获取它而只是为了改变它。