在我的主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方法是什么?
答案 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中重新获取它而只是为了改变它。