如果有一个类作为数据访问层,并为实体提供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)
答案 0 :(得分:2)
甚至还有第三种方法基于手动或自动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
,并且您将在全球范围内确认或放弃整个交易。
答案 1 :(得分:1)
EF的表现由几个因素组成,DbContext
的范围就是其中之一。
有关范围的一些背景信息,请访问:https://msdn.microsoft.com/en-us/data/jj729737.aspx
范围不仅与性能有关,还与返回的对象有关。如果在访问某些导航属性之前应用了延迟加载并且DbContext
已被释放,则会给出异常。见http://www.entityframeworktutorial.net/EntityFramework4.3/lazy-loading-with-dbcontext.aspx
您可以编写如下代码:
public class EmployeeService
{
public EmployeeDto GetEmployee(int id)
{
using(DbContext db=new DbContext())
{
return db.Employees.Select(e =>
new EmployeeDto
{
Id = e.Id,
Name = e.Name,
Department = e.Department.Name
}).First(e => e.Id == id);
}
}
}
public class EmployeeDto
{
public int Id { get;set;}
public string Name { get;set;}
public string Department { get;set;}
}
因此,您可以使用projection来限制返回的数据集,而不是返回整个对象。这可以用来减少数据库服务器上的负载,因为查询将更简洁,但它也有助于在处置上下文之前加载所有必需的数据。有关生成的查询的一些示例,请参阅http://www.entityframeworktutorial.net/querying-entity-graph-in-entity-framework.aspx。
所以我的建议是限制DbContext
的范围。你可以注入DbContext但是你无法控制DbContext
它会导致这样的错误:http://wallacekelly.blogspot.nl/2012/01/linq-to-entities-objectdisposedexceptio.html
但这完全取决于您的需求以及您正在建设的服务类型。