gpt4 book ai didi

c# - 在通用存储库中使用 IEnumerable 和 IQueryable

转载 作者:太空狗 更新时间:2023-10-29 19:39:37 25 4
gpt4 key购买 nike

我已经阅读了很多关于实现通用存储库的文章。我还阅读了一些帖子,这些帖子解释了从我的存储库中公开 IEnumerable 与 IQueryable 之间的区别。

我希望在数据库中(而不是在客户端的内存中)过滤我的数据的灵 active ,但希望避免为我的所有实体(以及实现这些接口(interface)的具体类)定义一个单独的存储库接口(interface).

到目前为止,我的存储库如下所示:

public interface IRepository<T>
{
IEnumerable<T> GetAll();
IEnumerable<T> Find(Expression<Func<T, bool>> where);

void Add(T entity);
void Attach(T entity);
void Delete(T entity);
}

具体实现的例子是:

public class Repository<T> : IRepository<T> where T : class
{
private DbContext _context;
private DbSet<T> _entitySet;

public Repository(DbContext context)
{
_context = context;
_entitySet = _context.Set<T>();
}

public IEnumerable<T> GetAll()
{
return _entitySet;
}

public IEnumerable<T> Find(Expression<Func<T, bool>> where)
{
return _entitySet.Where(where);
}

public void Add(T entity)
{
_entitySet.Add(entity);
}

public void Attach(T entity)
{
_entitySet.Attach(entity);
}

public void Delete(T entity)
{
_entitySet.Remove(entity);
}
}

在这种情况下,我的存储库使用 DbContext所以我想知道这是如何与通用接口(interface)一起工作的:

  1. IQueryable<T>源自 IEnumerable<T> .在我的查找方法中,我返回一个 IQueryable<T>对象,但客户端只将其视为 IEnumerable<T> .这是否意味着如果我对 IEnumerable<T> 执行任何后续查询对象它实际上会在数据库上执行操作并且只返回结果(因为对象是一个 IQueryable 在这种情况下)?或者,
  2. 只有 Where传递到 Find 的子句方法在数据库上执行,并且在 IEnumerable<T> 上执行的任何后续查询对象在客户端执行。或者,
  3. 这些都没有发生,我完全误解了 IEnumarable<T> , IQueryable<T>Linq有效。

更新:

实际上,我对评论中收到的答案感到相当惊讶。我的原始存储库返回了 IQueryable,随后的研究让我相信这是一件坏事(例如,如果我的 viewModel 在其构造函数中接受一个存储库,它可以调用它想要的任何查询,这使得它更难测试)。

到目前为止,我看到的所有解决方案都涉及创建特定于实体的存储库,以便不公开 IQueryable(我想唯一的区别是我以通用方式执行此操作)。

最佳答案

因为你要返回IEnumerable<T>所有后续调用都将在内存中(本地)完成。

要记住的一件事是,LINQ 使用一组扩展方法进行操作。 IQueryable<T> 有扩展方法它支持在本地以外的位置执行查询所需的所有连接,以及 IEnumerable<T> 的扩展方法。只在本地工作。

请注意,选择其中的哪一个是基于编译时类型,而不是运行时类型。所以IQueryable被转换为 IEnumerable将被视为 IEnumerable .这与类通常的工作方式不同(由于多态性),但它允许调用站点控制如何执行这些操作。

当您需要获取表中的所有记录然后对它们进行计数时,这是一个有用的例子。如果无论如何要获得所有结果,则无需在 SQL 中执行计数。

关于c# - 在通用存储库中使用 IEnumerable<T> 和 IQueryable<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11746841/

25 4 0