如果有一个类充当数据访问层,并为实体提供CRUD操作的功能,则在考虑性能和多线程环境时(即此类的方法同时被多个线程调用),哪种版本是最佳实践。 )。 。 。
版本1:
在类级别创建的DbContext,由所有方法共享。 。
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();
}
}
版本2:
每个方法调用的DbContext。 。
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();
}
}
}
更新:
可能是发布的问题在范围上太笼统,导致需要考虑几点。
有趣的是,实例化DbContext对象的成本。可以根据请求创建它(版本2)还是重对象,最好创建几个实例并在不同的调用之间共享它们(版本1)
最佳答案
甚至还有基于手动或自动dependency injection的第三种方法:
public interface ISomeService
{
// Interface members
}
public class SomeService : ISomeService
{
public SomeService(DbContext dbContext)
{
DbContext = dbContext;
}
private DbContext DbContext { get; }
}
然后,
SomeService
不会负责定义注入的DbContext
的生命周期,但是它是由外部类来完成的。这样,您的服务就专注于完成预期的工作(使用域并读取/写入数据)。
根据执行环境,您将需要不同的
DbContext
生活方式:每个服务实例,每个请求,每个线程...根据情况,这里有很多选择。也许您没有考虑另一种情况:两个或多个服务之间的共享事务。您需要将实例化
DbContext
的职责转移到上层,然后将相同的DbContext
注入所有参与的服务,然后您将在全局范围内确认或放弃整个交易。关于c# - dbContext全局范围与方法级别范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38932558/