Using statement in Entity Framework - asp.net-mvc

I would like to ask about "using" statement in Entity Framework. As I saw several time in other forums and books, that it's a good practice when you are quering database using following code (from ASP.NET MVC4 Appliocation):
using (var db = new ProductsEntites())
{
var result = db.Products.ToList();
return View(result);
}
But in other hand, if we are using scaffolding to generate contorller methods and view, default generator is declaring
private ProductsEntites db = new ProductsEntites()
at controller level, so in this case memory that are used to store query results are released only when timeout usage expired and garbage collector unlock memory for other needs. So what is better for small web site and what is best for big

You can override Dispose method of the controller. It should be called in the end of request.
protected override void Dispose(bool disposing) {
if(disposing)
db.Dispose();
}

having
private ProductsEntites db = new ProductsEntites()
as a class variable and Dispose it in the controllers Dispose Method seems fine to me. Like Mehmet Ataş pointed out:
protected override void Dispose(bool disposing) {
if(disposing)
db.Dispose();
}
The controller is disposed after the execution of an action.

The Entity Framework was developer to works fine even you not call the Dispose method (when you using a using statement you are implicity calling Dispose method).
It works fine because the EF use a Design Pattern call Fly Weight. In essence a piece of data always remains in memory. It's because that the EF has a delay in first execution of server, and when you kill de aplication has a delay to.
So you can use the code like scaffolding template without worrying about.

be wary of the using statement with EF, ensure that all your IQueryable returns are materialised by converting them into an IEnumerable by using ToList or ToArray etc.
If you don't, lazy loading could try and access the context to grab some navigation properties as they are used, if the context is disposed, you will get an exception thrown.

Related

Dispose DbContext in MVC Controller, which way "better"?

In MVC 5, the scaffolding codes will have something like:
public class MyController : Controller
{
private MyContext db = new MyContext();
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
otherwise, I need to have
using (var db = new MyContext())
{...}
in each action.
The codes look good, so I don't need to use using in each action. However, is this subject to preference of programmers, or such style has some advantage over using in each action that needs to use the dbcontext?
Both solution are good - both solution will dispose db context. But in my opinion the second option will be better - you create db context just where you have to.
But what if another class (some service class) also uses db context. It is good practice to have one db context for the whole web request. In that case you should pass previous created db context to all classes that use db context to prevent creating new db context in all clases. So I will consider usage of IoC containers. IoC container will resolve your dependencies and also will mange object lifetime. Bellow
I listed a few IoC containers:
Castle Windsor
Spring Framework
StructureMap
For simple scenarios calling Dispose (or using Using) is not necessary at all :)
"The default behavior of DbContext is that the underlying connection is automatically opened any time is needed and closed when it is no longer needed."
From here:
http://blog.jongallant.com/2012/10/do-i-have-to-call-dispose-on-dbcontext/
In terms of best practices, you should absolutely use the template scaffolded stuff and not mess with the using(){} pattern unless you have some really good overriding reason. Both solutions produce the same result, but both are not good solutions. The reason why the template has a single DbContext is to make it easier to test - heres an example:
public class SomeController : Controller
{
private ApplicationDbContext db;
public AccountController()
{
db = new ApplicationDbContext();
}
public AccountController(ApplicationDbContext context)
{
db = context;
}
}
The first constructor with no arguments is that which is used in production and automatically creates a new db context based on the app config file. The second allows you to inject a mocked db context when you are doing unit testing.
At the end of the day, this question and my answer isn't really about disposing db contexts - it's about why the code template designers chose to take the approach they did and why it will help you. You should read more on unit testing.
A Using statement calls the Dispose() method at the end of the Using block automatically. The Using statement calls the Dispose() method even if there was an error in the code.

When/How to dispose DbContext when returning IQueryable?

I've recently started using IQueryable inspired by http://www.codethinked.com/keep-your-iqueryable-in-check. So I've been used to doing this in my repos:
public IEnumerable<POCO> GetById(int id)
{
using (var ctx = new DbContext())
{
var query = from ...;
return query.ToList();
}
}
Now I'm doing this instead:
public IPageable<POCO> GetById(int id)
{
var ctx = new DbContext()
var query = from ...;
return new Pageable(query);
}
But I'm wondering if this is the best way to handle new DbContext().
Is it better to place DbContext as a class member
public class Repo
{
private DbContext _ctx = new DbContext();
}
Or even injection it
public class Repo
{
private DbContext _ctx;
public Repo(DbContext ctx)
{
_ctx = ctx;
}
}
What are the pros and cons to:
a new DbContext in each method.
a new DbContext per object (class member).
injecting DbContext.
I'm using Ninject so I can use .InRequestScope(); (if that should effect the answer)
A couple other questions:
Should my repo implement IDisposable if DbContext is kept as a class
member?
Is there an even better way to handle disposal of DbContext then the above?
I would always go with injecting the DBContext, with the InRequestScope. Gives all benefits of dependency injection.Ninject would also dispose the DBContext on the end of the cycle as DBContext implements IDisposable. See this thread
If you use DI, your other two questions become irrelevant.
Entity Framework loves caching. If you are constantly changing your application and reloading it in your browser, you'll probably notice that the first time you reload it, it takes a couple of seconds to load, but after that, pages are almost instantaneous. This is because MVC and EF are caching common queries that are repeatedly used, making your app faster to use after that initial load time.
Because of this, it is not of huge concern where you create your DBContext. Yes, creating anything takes time. However, EF will recognize these queries and will load them quickly, even if you have just created a new instance of your context.
On a side note, if your application doesn't have a large amount of queries, the use of Using blocks around your DbContext would be considered ideal (as this handles the dispose for you), but again, the runtime and memory use results would be negligible.

What is the correct place to dispose a repository created in a custom controller factory?

In my ASP.NET MVC project I use a custom controller factory that instantiates an Entity Framework-based data repository and passes it to the controller's constructor. The repository object implements IDisposable, but where should I call its Dispose method? The most straightforward approach that comes to mind is to override the controller's Dispose method and do it there, but since the repository was injected into the controller and not created there, disposing it in the controller doesn't seem quite right to me.
In your repository, you should use the Entity Framework data contexts within a using statement. This means that after the data access is finished the Dispose method will be called on the context, closing the connection.
using(var context = new MyDbContext())
{
//do your data access
}
I guess is a little late by now, but you do it in the ReleaseController method of your IControllerFactory.
Take a look at this: http://www.jasinskionline.com/technicalwiki/(S(wvw00ibwlzs5na45orv53qyl))/Custom-Controller-Factory-Putting-Controllers-in-an-External-Assembly-ASP-NET-MVC.ashx?AspxAutoDetectCookieSupport=1

class instance per request in asp.net mvc

I'm new with asp.net mvc. I have an app class which only needs one instance per request. It has IDispose so i'll need it to be dispose properly and I call it every page hit.
The problem I am finding is I sometimes needs to call methods in my view. I have no idea how I can access the class in the controller, view and have it dispose properly at the end of each request. I get the feeling I need to replace ALL of my controllers with my own controller class as a base. But this would only work if it executes the view first and I can access members in MyController from the view (actually I can just stuff it into the viewbag can't I)
Whats the proper way of doing this?
One solution would be to wire up a Dependency Injection framework (such as Ninject) and let it control the object lifetime for you. Ninject has a InRequestScope lifetime policy, which will create one object per request, so subsequent calls to get the object will return the same object if it is in the same request.
After implementing the dependency injection you can dispose your dependencies or objects like below in the controller.
protected override void Dispose(bool disposing)
{
_requestRepository.Dispose();
base.Disposing(disposing);
}

ASP.net MVC Controller - Constructor usage

I'm working on an ASP.net MVC application and I have a question about using constructors for my controllers.
I'm using Entity Framework and linq to Entities for all of my data transactions. I need to access my Entity model for nearly all of my controller actions. When I first started writing the app I was creating an entity object at the beginning of each Action method, performing whatever work I needed to and then returning my result.
I realized that I was creating the same object over and over for each action method so I created a private member variable for the Entity object and started instantiating it in the constructor for each controller. Now each method only references that private member variable to do its work.
I'm still questioning myself on which way is right. I'm wondering A.) which method is most appropriate? B.) in the constructor method, how long are those objects living? C.) are there performance/integrity issues with the constructor method?
You are asking the right questions.
A. It is definitely not appropriate to create this dependencies inside each action method. One of the main features of MVC is the ability to separate concerns. By loading up your controller with these dependencies, you are making the controller for thick. These should be injected into the controller. There are various options for dependency injection (DI). Generally these types of objects can be either injected into the constructor or into a property. My preference is constructor injection.
B. The lifetime of these objects will be determined by the garbage collector. GC is not deterministic. So if you have objects that have connections to resource constrained services (database connections) then you may need to be sure you close those connections your self (instead of relying on dispose). Many times the 'lifetime' concerns are separated out into an inversion of control (IOC) container. There are many out there. My preference is Ninject.
C. The instantiation costs are probably minimal. The database transactions cost are where you probably want to focus your attention. There is a concept called 'unit of work' you may want to look into. Essentially, a database can handle transactions larger than just one save/update operation. Increasing the transaction size can lead to better db performance.
Hope that gets you started.
RCravens has some excellent insights. I'd like to show how you can implement his suggestions.
It would be good to start by defining an interface for the data access class to implement:
public interface IPostRepository
{
IEnumerable<Post> GetMostRecentPosts(int blogId);
}
Then implement a data class. Entity Framework contexts are cheap to build, and you can get inconsistent behavior when you don't dispose of them, so I find it's usually better to pull the data you want into memory, and then dispose the context.
public class PostRepository : IPostRepository
{
public IEnumerable<Post> GetMostRecentPosts(int blogId)
{
// A using statement makes sure the context is disposed quickly.
using(var context = new BlogContext())
{
return context.Posts
.Where(p => p.UserId == userId)
.OrderByDescending(p => p.TimeStamp)
.Take(10)
// ToList ensures the values are in memory before disposing the context
.ToList();
}
}
}
Now your controller can accept one of these repositories as a constructor argument:
public class BlogController : Controller
{
private IPostRepository _postRepository;
public BlogController(IPostRepository postRepository)
{
_postRepository = postRepository;
}
public ActionResult Index(int blogId)
{
var posts = _postRepository.GetMostRecentPosts(blogId);
var model = new PostsModel { Posts = posts };
if(!posts.Any()) {model.Message = "This blog doesn't have any posts yet";}
return View("Posts", model);
}
}
MVC allows you to use your own Controller Factory in lieu of the default, so you can specify that your IoC framework like Ninject decides how Controllers are created. You can set up your injection framework to know that when you ask for an IPostRepository it should create a PostRepository object.
One big advantage of this approach is that it makes your controllers unit-testable. For example, if you want to make sure that your model gets a Message when there are no posts, you can use a mocking framework like Moq to set up a scenario where your repository returns no posts:
var repositoryMock = new Mock<IPostRepository>();
repositoryMock.Setup(r => r.GetMostRecentPosts(1))
.Returns(Enumerable.Empty<Post>());
var controller = new BlogController(repositoryMock.Object);
var result = (ViewResult)controller.Index(1);
Assert.IsFalse(string.IsNullOrEmpty(result.Model.Message));
This makes it easy to test the specific behavior you're expecting from your controller actions, without needing to set up your database or anything special like that. Unit tests like this are easy to write, deterministic (their pass/fail status is based on the code, not the database contents), and fast (you can often run a thousand of these in a second).

Resources