Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring Entity FrameWork Contexts with using

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?

like image 523
user2067567 Avatar asked Apr 17 '13 11:04

user2067567


3 Answers

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)

like image 102
paul Avatar answered Oct 19 '22 08:10

paul


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();

like image 26
kingdango Avatar answered Oct 19 '22 07:10

kingdango


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!

like image 3
MaxSC Avatar answered Oct 19 '22 08:10

MaxSC