I’m working on project in WPF, using local database (via SQL Express) and Entity Framework as a ORM.
I want to implement as many ViewModels as View classes. Kind of 1 to 1 relation, I’ve heard that’s a good way to implement MVVM (if you don’t agree, please share why). My vision of this is that every ViewModel serve its View (ie. sharing some data from database provided by Model layer).
So every View has its ViewModel which is kind of servant. 😉
During implementing this conception I came across the problem… Let’s assume that at least 2 ViewModels want to get recent list of all the customers stored in database.
What would I do in this case? I would have to add this code to all of these ViewModels (against DRY):
public ObservableCollection<Customer> Customers;
private ObservableCollection<Customer> GetAllCustomers()
{
var oc = new ObservableCollection<Customer>();
using (var db = new MyDbContext())
{
var query = from b in db.Customers
orderby b.Surname
select b;
foreach (var customer in query)
{
oc.Add(customer);
}
}
return oc;
}
or (alternatively) I would make some static FooClass with the same code I wrote above, but singed as static. It’s not very clever because such a FooClass would be big pile of mess after some time.
I can’t find any smarter solution. I’m sure you know how I should code it in clever way. So please help me. How should I provide the same functionality to many ViewModels?
You should abstract your data access in the consuming code into some layer that allows for your specific data access and/or indirection. A simple breakdown is to take the custom queries that you have, place them in an object and reference that object in your different viewmodels.
Below is an oversimplified example that leaves room for improvement but should give you a general idea, not sure how practical the viewmodel method is as below either but again providing an example for the stated code.
…
Along with this example you would probably want to split out
DataAccessinto aggregate root classes that deal with specific sets of data and can handle query criteria passed by the client, there are also other considerations such as not allowing the consumer to consume data entities but rather DTOs or domain objects and layers for specific business logic as well. The long and short of it is I wouldn’t recommend accessing your EF data context directly from your viewmodels unless this is just toy/prototype code.