简体   繁体   中英

Entity Framework Repository Pattern with WPF

I have watched Mosh Hamedani's course on EF as well as read articles on MSDN. I have also read a few discussions here in StackOverflow over this. But I cannot still understand it properly.

I am trying to use Entity Framework with repository pattern in WPF. Now, everywhere I see people using repository pattern in such a way that it returns a IEnumerable<> of items. However, since I am trying to bind these to datagrids which needs to be updated, is it not better to return ObservableCollection?

Also, I watched a few tutorials where they blindly remove and replace ICollection and Hashset in the entities created by EF with ObservableCollection. However, there is a tutorial where it says, and I quote, "Find and replace the first occurrence of “HashSet” with “ObservableCollection”. This occurrence is located approximately at line 50. Do not replace the second occurrence of HashSet found later in the code." It does not even explain why I shouldn't replace the second occurrence at all.

Can anyone tell me how to understand which ICollection and Hashset are safe to be replaced with ObservableCollection?

As a side note, I have introduced INotifyPropertyChanged in Entities. Is it better practice to use ObservableObject?

Any help would be genuinely welcome.

The best practices suggest to segregate all the responsibilities, ideally once per class. There is no reason that a contract of a repository pattern returns a collection of type ObservableCollection<> . This is not needed and add unnecessary overheads.

To properly bind an UI element to your repository pattern and updates the data source accordingly, we are introducing another responsibility: the coordination of the update of the data. You can typically implement this responsibility using the MVVM pattern, where your view model expose your initial IEnumerable<> collection to an ObservableCollection<> to your view and call your repository when updates are triggered.

Thus, the workflow to load data becomes:

Repository( IEnumerable<> ) --[LOAD]--> ViewModel( ObservableCollection<> ) --> View

and the workflow to update data becomes:

View --[UPDATE]--> ViewModel --[PROPAGATE]--> Repository

The view model takes care of the ObservableCollection<> which is a need of the UI layer and calls the right method(s) of your repository (for example repo.Save(myItem) ) to keep the data source updated.

You got confused because you wish to use in one hand the repository pattern, that should introduce a notion of abstraction (the implementation can be replaced by anything) and the Microsoft guide, that suggests to implement a strong coupling between your data and UI layers.

The bottom line here is either you go with what Microsoft suggest with a strong coupling, or with a loosely coupled solution using a repository pattern. Nonetheless, if you try to do the both at the same time, you are going to end up with a leaky abstraction and only get the drawbacks of the two solutions.


EDIT to suggest a contract for the repository.

public interface ItemsRepository
{
   IEnumerable<Item> GetAll();
   void Update(Item item);
}

Then, the UI layer will only reference this interface to interact with your database. You can now implement it with any ORM library or why not a web service if you suddently need to.

What you need is to decouple your UI from your data layer.
The repository is responsible for managing you data access code (read/write to the db)

Now,how you display and edit your data on the UI is not the repository's problem.
You need a business/presentation layer.

For example,if you have a CustomerRepository like

class CustomerRepository
{
    public IEnumerable<Customer> GetCustomers()
    {
         return yourContext.Customers.ToList();
    }
}

You can create a service like

class CustomerService
{
    public ObservableCollectionOf<Customer> GetCustomers()
    {
         var customers=new CustomerRepository().GetCustomers().OrderBy...;
         return new ObservableCollectionOf(customers);
    }
}

You don't have to ,and probably shouldn't ,use UI(InotifyPropertyChanged,Observables) related code on you Entities.

Create ViewModels (in your Business/Presentation Layer) which are responsible for that

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM