2009-12-26 5 views
2

Dans mon principal Window1.xaml.cs, je construis une ObservableCollection de ViewModels comme celui-ci par l'instanciation d'un objet modèle LINQ to SQL:Passage d'un DataContext L2S dans un constructeur ViewModel Nettoyer MVVM?

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

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

Dans le constructeur de chaque ViewModel, je enregistrer l'objet LINQ to SQL interne et la carte toutes les propriétés du modèle à 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; 
    ... 
} 

le problème est que lors de la manipulation des événements dans mon ViewModel, par exemple après que l'utilisateur change l'un des champs et clique sur le bouton Save, je dois réinstancier un objet LINQ-to-SQL afin d'enregistrer les modifications, ce qui entraîne plus de trafic vers et depuis la base de données alors que j'avais déjà l'objet enregistrement interne:

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

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

la solution immédiate est de passer la LINQ to SQL objet datacontext jusqu'à la ViewModel et lors de l'instanciation ViewModel, comme ceci:

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

    FirstName = customer.FirstName; 
    ... 
} 

et puis quand gérer mes événements s uch comme le bouton Save, je pourrais simplement appeler SubmitChanges() sur le interneDb variable sans le réintégrer et récupérer les données de la base de données à nouveau.

Il semble que je dois soit (1) passer un objet de contexte dataLayer dans le ViewModel qui ne semble pas être une manière propre MVVM de résoudre ce problème, ou (2) Je dois REFETCH mon Objet LINQ-to-SQL chaque fois que je souhaite enregistrer l'objet de modèle que j'ai déjà enregistré en interne dans le ViewModel. Quelle est l'approche MVVM la plus propre pour résoudre ce dilemme?

Quelle est l'approche MVVM la plus propre pour résoudre ce dilemme?

Répondre

2

Cela signifie que votre ViewModel a des connaissances sur le datalayer. Je pense qu'il est préférable d'utiliser le contexte d'initialisation d'objet. Cela vous permet également de le faire:

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

    CustomerCollection.AddRange(customers); 
} 

Lors de la mise à jour de la base de données, vous devriez être en mesure de créer un nouvel objet, puis utiliser db.AttachObject pour rendre le contexte conscient. Cela vous évite d'avoir à le ré-extraire de la base de données juste pour le changer.

+0

+1 pour joindre. C'est la bonne approche. Les ViewModels stockent l'objet modèle dans une propriété Model et utilisent simplement attach lorsque vous faites un round-trip. –

+0

@Anderson: Je ne pense pas que l'attachement de l'objet modèle au viewmodel soit une bonne idée. Il n'est pas remis en série lors du déclenchement d'un message de page, et il introduit également un couplage étroit entre les deux. Le viewmodel devrait juste contenir des données, rien de plus .. –

+0

C'est un * View ** Model * C'est le point. Les deux mots sont importants ici. J'ai vu beaucoup de gens introduire une autre construction comme un contrôleur qui agit comme une couche lubrifiante entre un viewmodel et le modèle, mais je ne considérerais pas cela comme un must-have. –

Questions connexes