0

I'm new to MVC, EF and the like so I followed the MVC3 tutorial at http://www.asp.net/mvc and set up an application (not yet finished with everything though).

Here's the "architecture" of my application so far

  • GenericRepository
  • PropertyRepository inherits GenericRepository for "Property" Entity
  • HomeController which has the PropertyRepository as Member.

Example:

public class HomeController
{
    private readonly PropertyRepository _propertyRepository 
          = new PropertyRepository(new ConfigurationDbContext());
}

Now let's consider the following:

I have a Method in my GenericRepository that takes quite some time, invoking 6 queries which need to be in one transaction in order to maintain integrity. My google results yeldet that SaveChanges() is considered as one transaction - so if I make multiple changes to my context and then call SaveChanges() I can be "sure" that these changes are "atomic" on the SQL Server. Right? Wrong?

Furthermore, there's is an action method that calls _propertyRepository.InvokeLongAndComplex() Method. I just found out: MVC creates a new controller for each request. So I end up with multiple PropertyRepositories which mess up my Database Integrity. (I have to maintain a linked list of my properties in the database, and if a user moves a property it needs 6 steps to change the list accordingly but that way I avoid looping through all entities when having thousands...)

I thougth about making my GenericRepository and my PropertyRepository static, so every HomeController is using the same Repository and synchronize the InvokeLongAndComplex Method to make sure there's only one Thread making changes to the DB at a time.

I have the suspicion that this idea is not a good solution but I fail to find a suitable solution for this problem - some guys say that's okay to have static repositories (what happens with the context though?). Some other guys say use IOC/DI (?), which sounds like a lot of work to set up (not even sure if that solves my problem...) but it seems that I could "tell" the container to always "inject" the same context object, the same Repository and then it would be enough to synchronize the InvokeLongAndComplex() method to not let multiple threads mess up the integrity.

Why aren't data repositories static? Answer 2:

2) You often want to have 1 repository instance per-request to make it easier to ensure that uncommited changes from one user don't mess things up for another user.

why have a repository instance per-request doesn't it mess up my linked list again?

Can anyone give me an advice or share a best practice which I can follow?

Community
  • 1
  • 1

1 Answers1

1

No! You must have a new context for each request so even if you make your repositories static you will have to pass current context instance to each its method instead of maintaining single context inside repository.

What you mean by integrity in the first place? Are you dealing with transactions, concurrency issues or referential constraints? Handling all of these issues is your responsibility. EF will provide some basic infrastructure for that but the final solution is still up to your implementation.

Community
  • 1
  • 1
Ladislav Mrnka
  • 349,807
  • 56
  • 643
  • 654
  • I create a new Context in the HomeController constructor. So I'd have a new one per-request. But I need to use the same instance for all my Repositories? By integrity I mean a Linked List in the database, so when manipulating (adding / removing / moving) an entity I need to make sure that not 2 threads are manipulating the list. – B.Delorme Nov 18 '11 at 13:02
  • My entity/table looks like in this SO-post here: http://stackoverflow.com/questions/675117/fetching-linked-list-in-mysql-database . I try to explain my problem with this question: If two users are changing the Node with ID 4 (User1 to head, User2 to tail) my List is "messed up" means I cannot retrieve the nodes because there are Parents with same IDs. Ok when I'd use the same context for all repositories in one request everything should be fine. My problem is that when I generate a second request during the move operation I get an error that there's no element in the sequence. – B.Delorme Nov 18 '11 at 13:32
  • One context will not help you. It will result in the same problem because multiple threads will change single entity and once any thread calls SaveChagnes it will save incomplete changes from other threads as well. You are looking for [concurrency handling](http://blogs.msdn.com/b/alexj/archive/2009/05/20/tip-19-how-to-use-optimistic-concurrency-in-the-entity-framework.aspx). – Ladislav Mrnka Nov 18 '11 at 13:42