- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在构建一个存储库,我在很多地方看到了两个不在存储库外公开 IQueryable 的原因。
1) 首先是因为不同的 LINQ 提供程序可能有不同的行为,这种差异应该包含在存储库中。
2) 第二个是防止服务级别开发人员修改数据库查询,从而意外导致性能问题。
我想问题 2 只能通过将所有查询逻辑保留在存储库中并且不允许任何形式的外部查询构建来避免吗?但这对我来说似乎有点不切实际。
问题 1 似乎可以通过使用数据对象模式来解决。
例如public IEnumerable<T> FindBy(Query query)
我的问题是,为什么我不直接传递一个 lambda 表达式,因为它独立于提供者,似乎可以为我提供与查询对象相同的功能,以及相同的分离级别?
例如public IEnumerable<T> FindBy(Expression<Func<T,bool>> predicate)
有什么理由不这样做吗?它是否违反了某些规则?最佳实践?我应该知道什么?
最佳答案
IQueryable<T>
.在您编写另一段“存储库代码”之前,您将从阅读 Ayende 的文章 Architecting in the Pit of Doom - The Evils of the Repository Abstraction Layer 中受益匪浅。
Generic List of OrderBy Lambda 中另一个问题的所有代码除了用不必要和不熟悉的抽象来掩盖现有的有效 API 之外,没有做任何事情。
关于您的两个问题,
LINQ 提供程序的行为确实不同,但只要您传递的谓词可以由 LINQ 提供程序处理,这就无关紧要。否则,您仍然会遇到同样的问题,因为您传递的是 Expression
。 , 它被传递给 IQueryable
无论如何最终。如果IQueryProvider
实现不能处理你的谓词,那么它就不能处理你的谓词。 (如果您需要在无法翻译的进一步过滤之前进行评估,您可以随时调用 ToList()
)。
修改查询可能会导致性能问题,但更有可能公开急需的功能。此外,与为避免暴露 IQueryable
而提取比您需要的记录更多的记录所导致的性能问题相比,次优 LINQ 查询引起的性能问题可能要小得多。或者通过实际上不做任何事情的臃肿抽象级别系统地过滤任何数据访问逻辑(第一个威胁更为重要)。一般来说,这不会成为问题,因为大多数领先的 LINQ 提供商会在翻译过程中优化您的查询逻辑。
如果您想对前端隐藏您的查询逻辑,那么不要尝试创建通用存储库。使用实际的业务特定方法封装查询。现在,我可能错了,但我假设您对存储库模式的使用是受领域驱动设计的启发。如果是这种情况,那么使用存储库的原因是允许您创建一个主要关注域模型的持久性无知域。然而,使用这种通用存储库除了将语义从 Create Read Update Delete
至 Find Add Remove Save
.那里没有嵌入任何真正的业务知识。
考虑一个
的意义(和可用性)interface IPersonRepository
{
Person GetById(int id);
IEnumerable<Person> FindByName(string firstName, string lastName);
}
相对于
interface IRepository<T> {
IEnumerable<T> FindBy(Query<T> query);
}
此外,您能否指出使用 IRepository<T>
的好处?完全没有(而不是 IQueryable<T>
)?
此外,请考虑使用通用方法,您实际上根本没有封装查询逻辑。您最终在外部构建它,这将导致更多额外的不必要代码。
*关于建议不要使用 IQueryable<T>
的资源的另一条注释, 是否值得查看它们的发布日期。曾经有一段时间,LINQ 提供程序的可用性非常有限(仅限于早期的 EF 和 LINQ-to-SQL)。当时暴露一个IQueryable<T>
将导致与 Microsoft ORM 的一些更流行的替代品不兼容(LINQ-to-NHibernate 早已实现)。目前,LINQ 支持在严肃的 ORM .NET 库中几乎无处不在
关于c# - 存储库/IQueryable/查询对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11964578/
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
我是一名优秀的程序员,十分优秀!