1

My C# application uses the Repository Pattern, and I have a terrible doubt as how to implement the "Update" part of CRUD operations. Specifically, I don't know how to "tell" the repository which object I want to replace (so that persistence can be carried out aftwerwards.

I have the following code in a console application (written just as example) that uses the libraries from the application:

class Program
{
    static void Main(string[] args) {

        var repo = new RepositorioPacientes();

        var listapacientes = repo.GetAll();

        // Choosing an element by index
        // (should be done via clicking on a WPF ListView or DataGrid)
        var editando = listapacientes[0];  

        editando.Nome = "Novo Helton Moraes";

        repo.Update(editando);

    }

}

Question is: How am I supposed to tell the repository which element it has to update? Should I traverse the whole repository using an equality comparer to find the element?

NOTE: this repository encapsulates data-access using XML serialization, one file per entity, and my entities (of type Paciente in this example) have the [Serializable] attribute. That said, the "Update" operation would end up replacing the XML file of the given entity with another with updated data, via Serialize method.

I am not concerned with that, though. what I cannot figure out is how to implement repo.Update(entity) so that the repo knows that this entity that is being passed back is the same that has been selected from listapacientes, which is not the repository itself.

Thanks for reading!

heltonbiker
  • 26,657
  • 28
  • 137
  • 252

3 Answers3

1

Ultimately, this should come down to the time-space trade off. Your suggestion of implementing an equality comparer and iteration through the entire repository maximizes runtime but uses little space by using a List<T> as the data structure used by the repository. In the worst case, where you update the last element of the list, you will need to iterate through the entire thing and run the equality operation on each element until it matches the last one. This is feasible for smaller repositories.

Another very common solution would be to override the GetHashCode of your T types in the repository, and using a HashSet<T> or Dictionary<T, V> as the data structure in the repository. The latter would minimize time to O(1) but take more space for the data structure. This is probably a better solution for much larger repositories, especially so if each of the type T objects has one property, like a GUID or database identifier associated with it that is unique because then you have a very easy hash value.

There are other data structures you can consider for your repository based on the exact use-case of your repository. For example, if you are trying to maintain an ordering of elements in the repository where only the highest or lowest element is fetched at a time, a PriorityQueue or Heap might be for you. If you spend time thinking about the data structure that backs your repository, the rest of the implementation should solve itself.

welegan
  • 3,013
  • 3
  • 15
  • 20
  • I think your key contribution for my understanding is "data structure that backs your repository". Until now, I was not even loading it to memory, since `GetAll` method just returned the collection, without even caching it inside the repo itself... By the way, since I plan to use this repo inside WPF with DataBinding, do you think a public, `ObservableCollection` could be used as backing structure? Or more boldly, simply make my repository inherit from `ObservableCollection` and implement CRUD methods? Application is rather simple. – heltonbiker Oct 16 '13 at 21:18
  • If your application is small scale then it won't really matter what data structure you use to back it in memory right away. You should use something that is fast to develop and you understand, while leaving the code abstract enough so you can change it later. Since you suggested using a repository, I assume you have abstracted enough of your code to do this already. In that case, the `ObservableCollection` MSDN page recommends you inherit it like you said so I feel like that is a good way to go for your needs. – welegan Oct 17 '13 at 14:14
  • Oh and Sunil's answer is very important if you are dealing with tight memory constraints, but since your question stated you were more concerned about having to iterate through the entire collection, I assumed you wanted better run-time as opposed to space-usage. – welegan Oct 17 '13 at 14:15
1

Don't load everything into memory. Try it something like this.

class Program
{
    static void Main(string[] args) {

    var repo = new RepositorioPacientes();

    var editando = repo.SingleOrDefault(p => p.Id == 1);

    editando.Nome = "Novo Helton Moraes";

    repo.Update(editando);
  }

}
sunil
  • 5,078
  • 6
  • 28
  • 33
0

you can use this link: http://www.codeproject.com/Articles/644605/CRUD-Operations-Using-the-Repository-Pattern-in-MV

And try this code

    public ActionResult Edit(int id)
        {
    Book book = _bookRepository.GetBookByID(id);
    return View(book);
    }  
     [HttpPost]
    public ActionResult Edit(Book book)
    {
      try
       {
         if (ModelState.IsValid)
          {
           _bookRepository.UpdateBook(book);
           _bookRepository.Save();
           return RedirectToAction("Index");
          } 
         }
          catch (DataException)
          {               
           ModelState.AddModelError("", "Unable to save changes. Try again, " + 
           "and if the problem persists see your system administrator.");
        }
            return View(book);
       }