views:

130

answers:

3

I am not very sure what design pattern is the most efficent to use when working with ASP.Net MVC and the Entity Framework, so any guidance is much appreciated!

Would you store the context in the Controller-class, or is it better to create a repository?

If you would recommend the repo-design, is it required to initialize the context in each method, like this? Or is it a better way to do this?:

public SomeEntity GetEntity(Guid id) {
   using(Context ctx = new Context()) {
      // code here...
   }
}
+3  A: 

I use the Repository pattern. The Context is in the Repository, and lasts as long as the Repository does. The Repository is initialized in Controller.Initialize and disposed in Controller.Dispose. This means one request gets a repository/context until the request is finished, which works very well -- requests are short, so the context is disposed quickly. But when an action invokes multiple repository methods, they all use the same context, which makes many things easier.

Craig Stuntz
Ok, thanks. But how would the Initialize()-method and the Dispose()-method look in the Repository?
Mickel
They're methods of Controller, not Repository. You override them, call base, then allocate/dispose your Repository. In the Repository's constructor, new up an ObjectContext. In Dispose, dispose the context.
Craig Stuntz
Will the Repository not be allocated/disposed automatically if I set it as a class variable in the controller (and initializes it explicitly)?
Mickel
Craig, I watched the online presentation about EF , great work. Do you have any sample code that I can download to further learn how you do CRUD.
J.W.
Not yet, but I'll have something soon. Watch my blog.
Craig Stuntz
Mickel, no, instance fields are not automatically disposed.
Craig Stuntz
Ok, good to know. Thank you for the help, much appreciated!
Mickel
A: 

Repository pattern is the way to go

Depends on your project size, but if it's not trivial I'd recommend repository pattern because it's also much easier to maintain.

Open context as late as possible and close as soon as possible
Similar to connections, you should also release your context as quick as possible so do any additional processing before actually reading/committing to DB via EF. So. Keep your using blocks as short as possible.

Robert Koritnik
So you say that to keep the context alive during the whole request, as Craig suggested, is not the best practice?
Mickel
No. I'm just saying that you should do repository stuff together and as late as possible. Don't do any non-necessary processing within context lifetime. If you need to do multi repository stuff and they all relate to same context, do them together of course. You would also reuse the same DB Connection for multi calls if needed, wouldn't you? Thinking/Acting is similar here.
Robert Koritnik
A: 

I created my own generic repository class with interface:

public interface IRepository<T>
{
    //Retrieves list of items in table
    IQueryable<T> List();
    IQueryable<T> List(params string[] includes);
    //Creates from detached item
    T Create(T item);
    //Updates from detached item
    //Attached item can be change directly and using SaveChanges
    T Edit(T item);
    void Delete(int id);
    void DeleteObject(object item);
    T Get(int id);
    T Get(int id, params string[] includes);
    void SaveChanges();
}

It takes care of basic CRUD operation, it has also context. Over repository i have service classes that hold business login. Example:

public interface IProjectService
{
    IQueryable<Project> ListProjects();
    Project GetProjectByName(string name);
    Project GetProjectByID(int id);
    bool EditBasicProjectData(Project project);
    bool CreateProject(Project project);
    bool DeleteProject(int id);
    void SetCurrentProjectByID(int id);
}

Every service has necessary repositories. Controllers have services injected by NInject. Controller methods are short, they are only passing data from services to view (in both ways). That makes whole project easy testable. You can mock repository to test service. You can mock service to test controller.

LukLed