Performance 实体框架,在存储库而不是在服务层查询是否有任何性能改进?

Performance 实体框架,在存储库而不是在服务层查询是否有任何性能改进?,performance,entity-framework,linq,entity-framework-4,repository,Performance,Entity Framework,Linq,Entity Framework 4,Repository,实体框架,在存储库而不是在服务层查询是否有任何性能改进 实体框架是否有像SQL这样的性能改进引擎?它是否知道接下来的3个伪代码都只是1db调用,或者它首先真的得到一些filteredcontidiona,然后应用第二个条件 CASE A) clients.Where( someFilterConditionA); clients.Where( someFilterConditionB); return clients; CASE B) clients.Where( someFilter

实体框架,在存储库而不是在服务层查询是否有任何性能改进

实体框架是否有像SQL这样的性能改进引擎?它是否知道接下来的3个伪代码都只是1db调用,或者它首先真的得到一些filteredcontidiona,然后应用第二个条件

CASE A) 
clients.Where( someFilterConditionA); 
clients.Where( someFilterConditionB); 
return clients;

CASE B) 
clients.Where( someFilterConditionA).Where( someFilterConditionB); 
return clients;

CASE C) 
clients.Where( someFilterConditionA AND someFilterConditionB); 
return clients;

EF确实有优化,在您的3个案例之间应该没有任何差异。您可以轻松地运行SQL探查器来检查EF发送到DB的任何查询

就执行而言:无论在何处触发,成本都在执行中。这通常是调用.ToList/.First/.Any/.Count等的地方。我看到人们犯的最大性能错误如下:

var results = dbContext.ParentEntities.Where(x=> x.SomeCriteria == true).ToList();

// later down the call stack...

var results = repostitory.GetParents(criteria);
if (results.Count > 0) 
   // never actually use results, or do something like results.FirstOrDefault(), etc.
然后是不适当的延迟加载或急于加载,返回整个实体图,而实际只使用了几个字段

我遵循的模式是使用延迟执行/w存储库模式。这意味着,除了少数例外,我的存储库总是返回
IQueryable
。即使是只需要1个实体的方法。(即GetById())存储库管理低级规则,如授权和软删除系统的IsActive等,以及历史数据的时间考虑因素,但我让业务逻辑根据需要根据附加条件进一步细化查询,定义将选择哪些字段,以及在执行延迟查询之前如何检索数据

这种方法的好处是,我的存储库可以作为我的单元测试的一个简单的分界点,我只需要从模拟存储库返回实体列表之类的东西,以执行我的业务逻辑。从维护的角度来看,我的存储库非常精简。不需要为不同的标准或预期的返回类型使用许多类似的方法,也不需要将模糊的表达式树等传递到函数中以进行中继过滤。从性能的角度来看,让业务逻辑控制数据的过滤和使用方式给了我很大的灵活性,有助于确保查询能够轻松优化。我的业务逻辑可以:

  • 仅选择实体及其所需的相关实体中的字段
  • 只返回它需要的行。(.FirstOrDefault、.Skip.Take等)
  • 处理其他业务逻辑决策。(.任何、.计数等)
所有这些都不涉及存储库定义。存储库成为一个精简服务类,以方便测试

反对这种模式的理由是,拥有一个包含显式和静态查询的存储库会使优化索引的目标更为谨慎。我的反对意见是,索引优化应该基于系统的使用方式,而不是针对早期应用进行优化。静态存储库和查询意味着您需要维护大量额外的代码,并且在许多情况下运行次优查询。(即,返回
IEnumerable
)或者有很多方法返回不同的数据结构,或者有更少的方法返回整个实体,其中实际上只需要很少的细节。IMO:构建系统,使用系统,调整系统