【发布时间】:2011-02-15 17:45:17
【问题描述】:
我已经为 Entity Framework 4 实现了一个通用存储库。这是一个简化版本,其中 AllAppContainer 是 EF4 对象上下文:
public class Repository<T> where T : class
{
protected AllAppContainer objectContext;
protected ObjectSet<T> entitySet;
public Repository()
{
objectContext = new AllAppContainer();
entitySet = objectContext.CreateObjectSet<T>();
}
public int QueryCount(Func<T, bool> predicate)
{
int queryCount = entitySet.Count(predicate);
return queryCount;
}
}
一种方法是 QueryCount(),我想将它作为 SQL 的 select Count(*) ... where 行(不返回实际记录)。
直截了当?你会想……首先,让我们做一个非存储库版本的同一件事,对 Item 实体进行计数:
AllAppContainer allAppContainer = new AllAppContainer();
int nonRepCount = allAppContainer.Items.Count(item => item.Id > 0);
SQL Server Profiler 说生成的 SQL 是:
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Items] AS [Extent1]
WHERE [Extent1].[Id] > 0
) AS [GroupBy1]
哇哦!得分!
现在让我们使用我的 Repository QueryCount 调用它:
Repository<Item> repository = new Repository<Item>();
int repCount = repository.QueryCount(item => item.Id > 0);
这是生成的 SQL:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[SmallField] AS [SmallField]
FROM [dbo].[Items] AS [Extent1]
是的,EF 正在返回完整的数据集,然后在内存中对其调用 Count()。
为了好玩,我尝试将 Repository QueryCount 中的相关行更改为:
int queryCount = new AllAppContainer().CreateObjectSet<T>().Count(predicate);
和非存储库行:
int nonRepCount = allAppContainer1.CreateObjectSet<Item>().Count(item => item.Id > 0);
但是每个生成的 SQL 都和以前一样。
现在为什么所有这些存储库返回所有匹配记录然后计数都会发生,而不是非存储库?有什么方法可以通过我的通用存储库来做我想做的事,即在 db.我无法承受内存中计数的性能损失。
【问题讨论】:
标签: sql entity-framework repository generics