DbContext global scope vs method level scope

c# entity-framework entity-framework-6

Question

If there is a class which works as a data access layer, and provides the functionality of CRUD operations for entities, Which version is the best practice when considering performance & Multi threaded environment (i.e methods of this class are called by multiple threads simultaneously . .). . .

Version 1:

DbContext created at class level, shared by all the methods . .

    class EmployeeService{

     private DbContext db=new DbContext();

     public  Employee GetEmployee(int id)

         return db.Employees.Find(id);
     }


     public void AddEmployee(Employee employee){

         db.Employees.Add(employee);
         db.SaveChanges();
     }
}

Version 2:

DbContext for each method call . .

class EmployeeService{

     public  Employee GetEmployee(int id){
        using(DbContext db=new DbContext()){
         return db.Employees.Find(id);
        }
     }


     public void AddEmployee(Employee employee){         
        using(DbContext db=new DbContext()){                 
            db.Employees.Add(employee);
           db.SaveChanges();    
        }
     }
}

UPDATE: May be the question posted is too generic in scope which leads several points to consider.

The point of interest is, the cost of instantiating DbContext object. Can it be created per request (Version 2) or is it heavy weight object and better to create few instances and share them across different calls (Version 1)

1
1
8/13/2016 12:52:47 PM

Popular Answer

There's even a third approach based on manual or automatic dependency injection:

public interface ISomeService 
{
     // Interface members
}

public class SomeService : ISomeService
{
    public SomeService(DbContext dbContext)
    {
         DbContext = dbContext;
    }

    private DbContext DbContext { get; }
}

Then, SomeService won't be the responsible of defining the life-time of injected DbContext, but it's an external class who does it.

That way, your service focuses on doing just what's meant to do (working with the domain and reading/writing data).

Depending on the execution environment, you'll want different DbContext life-styles: per service instance, per request, per thread... There're a lot of choices here depending on the case.

Perhaps you're not considering another scenario: a shared transaction between two or more services. You would need to transfer the responsibility of instantiating DbContext to an upper layer, and then you would inject same DbContext on all participating services, and you would confirm or abandon the whole transaction globally.

2
8/13/2016 2:02:49 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow