- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我已经阅读了很多关于实现通用存储库的文章。我还阅读了一些帖子,这些帖子解释了从我的存储库中公开 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)一起工作的:
IQueryable<T>
源自 IEnumerable<T>
.在我的查找方法中,我返回一个 IQueryable<T>
对象,但客户端只将其视为 IEnumerable<T>
.这是否意味着如果我对 IEnumerable<T>
执行任何后续查询对象它实际上会在数据库上执行操作并且只返回结果(因为对象是一个 IQueryable
在这种情况下)?或者,Where
传递到 Find
的子句方法在数据库上执行,并且在 IEnumerable<T>
上执行的任何后续查询对象在客户端执行。或者,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/
var page = pagesRepository.GetPages(); var categoryPages = page.ChildCategoryPages; var articlePages
是否可以将 IQueryable 对象转换为 IQueryable,其中 T 是映射实体? (T 将是 POCO 类)。 提前致谢。 最佳答案 就 Cast() 它。假设它是相同类型的可查询。否则你可
我只是想知道为什么会有一个 IQueryable没有通用功能的版本? 最佳答案 The generic IQueryable is the one you use most often in meth
我有一个 IQueryable它是根据一些输入参数(排序和过滤器)创建的。 可以应用这个 IQueryable到 DbSet我有DbContext ? 例如: // create the query
我们正在尝试转换 IQueryable 的实例到 IQueryable , SpecificEntityObject类型仅在运行时已知。 我们已尝试使用下面的代码,该代码无法编译,因为类型或命名空间
最近几天我在互联网上搜索了解决方案,但没有找到我想要的。基本上,这是我的问题: 我有一个需要实现的接口(interface),它有一个返回 IQueryable 的方法(我无权访问该接口(interf
与IEnumerable相同对比IEnumerable .这是疏忽吗?或者当您没有指定类型来实现像 .Count() 这样的扩展时,是否存在问题? , .Where()等不可能? 最佳答案 来自doc
这是 Automapper 专业人员的问题。我已经尝试做查询映射好几天了——但没有成功。似乎 Automapper 不打算按照我想要的方式使用它。但也许我错了。那么问题来了…… 我有这样的类(clas
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭去年。 Improve th
我有一个类Something实现 ISomething .如何从 IQueryable 转换/转换到 IQueryable .当我尝试转换时,我能够编译,但转换的结果始终为 NULL。 背景:我这样做
我了解协方差,并且我知道一般来说在 v4.0 之前它在 C# 中是不可能的。 但是我想知道一个具体案例。有什么方法可以进行转换IQueryable至IQueryable通过以某种方式创建一个包装类,该
如果IQueryable接口(interface)在服务器中执行查询表达式,而不是像 IEnumerable 那样获取所有记录,为什么是IQueryable未被 IEnumerable 取代哪里可以更
这个问题在这里已经有了答案: Why covariance and contravariance do not support value type (4 个答案) 关闭 7 年前。 为什么编译器不
我想做这样的事情 public IQueryable GetPaged(IQueryable query, int startIndex, int pageSize) {
我正在开发一个使用新 Web API 的项目,我注意到有人从 Get 方法返回了一个 IQueryable。 我的理解是 IQueryable 可用于提高性能(延迟执行),但我认为 HTTP 连接另一
我正在重构我的 EF 存储库类以使其可测试,遵循这篇优秀博客文章中的建议: https://blog.iannelson.uk/testing-linq-queries/ 一切都很好,我也能够像在博客
我有一个包含 IQueryable 的通用函数其中每一行都包含一个具有一组属性的类的实例。 我有另一个类 (MyClass),它具有与上面的类 T 相同的一些属性...即相同的名称和数据类型。 我还有
我正在尝试使用 Automapper 将 IQueryable 映射到 IQueryable 以生成 Linq。我正在开发一个带有 Entity Framework 和 oracle 11g 的 We
我有一个对象是: IQueryable 我想将它传递给一个函数,该函数需要: IQueryable Foo 确实实现了 IFoo 为什么不能编译?什么是最好的转换方式来让这项工作发挥作用? 最佳答案
我有一个查询可以获取一些过滤后的数据,但它给了我一些奇怪的结果。使用 VS Code 调试器查看附件图像(var source 是一个 Queryable,类似于 _dbContext.ModelNa
我是一名优秀的程序员,十分优秀!