DbContext global scope vs method level scope

c# entity-framework entity-framework-6

Question

Which version of a class that serves as a data access layer and offers CRUD operations for entities is the best practise in terms of performance in a multi-threaded environment (i.e., methods of this class are called by several threads at once)?

Iteration 1:

Each method shares a DbContext that was generated at the class level.

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

Iteration 2:

DbContext is passed with 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: The question may be overly general in scope, which raises a number of issues.

The interesting part is at how much it costs to create a DbContext object.. Version 2 allows it to be constructed every request, but if it's a hefty object, it's probably best to create a small number of instances and distribute them over several calls (Version 1)

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

Popular Answer

A third strategy based on manual or automated insertion of dependencies exists as well:

public interface ISomeService 
{
     // Interface members
}

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

    private DbContext DbContext { get; }
}

Then, SomeService not be in charge of determining the lifespan of injectedDbContext but an outside class does it.

In this manner, your service concentrates on carrying out its intended functions (interacting with the domain and reading and sending data).

You'll need various things depending on the execution environment.DbContext life-styles: per request, per thread, and per service instance... Depending on the circumstances, there are several options available.

You could not be taking into account a different scenario: a shared transaction involving two or more services. You would have to delegate the duty of instantiatingDbContext and then inject the same into an upper layerDbContext on all included services, and you might choose to accept or reject the whole transaction internationally.

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