10

Which is the Best Practise in Declaring Entity FrameWork Contexts

function()
{
    DBContext context = new DBContext();

    //Entity code

    return ;
}

or

function()
{
    using(DBContext context = new DBContext())
    {
        //Entity code
    }
}

Do we need to use using in EntityFrameWork ? If yes my 2nd question

In DataAccess Layer am executing EF and storing the result in IEnumerable inside using

MY DL

function()
{
    IEnumerable something = null;
    using(DBContext context = new DBContext())
    {
        IEnumerable something = ....
    }
    return something;
}

In Controller

function()
{
    List some = something.ToList();
}

And in my controller am getting this as a list as i need to do some Find operation am getting

"The operation cannot be completed because the DbContext has been disposed Entity Framework"

Yes i can return a list from DL and it works fine

How do i handle this if i use using with IEnumerable?

Yoeri
  • 2,249
  • 18
  • 33
user2067567
  • 3,695
  • 15
  • 49
  • 77
  • 1
    I think this SO link is exactly what you asked: http://stackoverflow.com/questions/824330/should-entity-framework-context-be-put-into-using-statement?rq=1 – Conrad Clark Apr 17 '13 at 11:27
  • yes in case please check my 2nd question – user2067567 Apr 17 '13 at 11:29
  • possible duplicate of [Using Statement and Entity Framework](http://stackoverflow.com/questions/13826536/using-statement-and-entity-framework) – Habib Apr 17 '13 at 11:29

3 Answers3

8

You can avoid the lazy-loading EF behaviour by calling .ToList() on the IEnumerable before the context is disposed (i.e. within your using block)

paul
  • 21,653
  • 1
  • 53
  • 54
  • Yep, Still use using as Paul said. +1 given. You do still get a similar issue if your model has grandchild objects though. I haven't spent time solving that one yet. – Lotok Apr 17 '13 at 11:30
  • 1
    @James I think you can get your children/grandchildren by using `.Include()` in the original Linq statement – paul Apr 17 '13 at 11:39
  • The problem is that with large datasets, this will load the entire thing into memory, which is what you want to avoid in the first place by using cursors and IEnumerable. – Gudlaugur Egilsson Feb 05 '15 at 10:43
7

Yes, a using is the best practice because it cleans up your context. The Using statement is a shortcut for:

try {
    // Execute your code inside the using statement
}
finally {
    // Cleanup the context no matter what by calling .Dispose()
}

Keep in mind, your context likely returns IEnumerables and since EF supports lazy loading these objects won't be populated until you fetch them to a concrete collection (ie. yourResult.ToList()).

A common negative outcome occurs in this scenario:

public IEnumerable<Employee> GetEmployeesInAccounting()
{
    using(var myContext = new MyDbContext())
    {
        return myContext.Employees.Where(emp => emp.Department == 'Accounting');
    }
}

// Code that fails, Assuming Manager is a lazy loaded entity, this results in an exception but it compiles no problem
var acctEmps = GetEmployeesInAccounting();
var something = acctEmps.First().Department.Manager.Department;

You can avoid this by using the .Include(emp => emp.Manager) (linq extension method) and binding your result using .ToList();

kingdango
  • 3,979
  • 2
  • 26
  • 43
3

Your request will be executed toward the datasource as soon as you'll call .ToList() method.

That's why you cannot perform .ToList() in your Controller as your context as been disposed at the end of the using block.

In your DL method, just do something like:

IEnumerable<Something> function()
{
    using(DBContext context = new DBContext())
    {
      return something.ToList();
    }
}

and in your Controller you'll get an IEnumerable of Something:

var mySomethingIEnumerable = DL.Function();

Hope that helps!

MaxSC
  • 4,698
  • 2
  • 23
  • 36