开发者

Is passing a L2S DataContext into a ViewModel constructor clean MVVM?

In my main Window1.xaml.cs, I build an ObservableCollection of ViewModels like this by instantiating with a LINQ-to-SQL model object:

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

    foreach (var customer in customer开发者_运维问答s)
    {
        CustomerCollection.Add(new CustomerModelView(customer));
    }
}  

In the constructor of each ViewModel, I save the LINQ-to-SQL object internally and map all the properties from Model to 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;
    ...
}

The problem is that when handling events in my ViewModel, e.g. after the user changes any of the fields and clicks the Save button, I have to reinstantiate a LINQ-to-SQL object in order to save the changes, which incurs more traffic to and from the database when I actually already had the object saved internally:

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

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

The immediate solution is to pass the LINQ-to-SQL datacontext object down to the ViewModel as well when instantiating the ViewModel, like this:

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

    FirstName = customer.FirstName;
    ...
}

and then when handling my events such as the Save button, I could just call SubmitChanges() on the internal Db variable without reinstantiating it and get the data from the database again.

So it seems I have to either (1) pass a datalayer context object into the ViewModel which doesn't seem like a clean MVVM way of solving this problem, or (2) I have to refetch my LINQ-to-SQL object each time I want to save the model object that I already have saved internally in the ViewModel.

What is the cleanest MVVM approach to solve this dilemma?


This means your ViewModel has knowledge about the datalayer. I think it's better to use the object initializer context. This also allows you to do this:

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

    CustomerCollection.AddRange(customers);
}

When updating the database, you should be able to create a new object, and then use db.AttachObject to make the context aware of it. That saves you from having to re-fetch it from the DB just to change it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜