动态查询的最佳选择?
Posted
技术标签:
【中文标题】动态查询的最佳选择?【英文标题】:Best option for dynamic queries? 【发布时间】:2011-09-05 21:31:36 【问题描述】:我正在将一个旧应用程序从 WebForms 移植到 MVC,其中一部分过程是拆除现有的数据层,将逻辑从存储过程转移到代码中。因为我最初只使用基本的 C# SQL 函数 (System.Data.SqlClient),所以我使用了一个轻量级的伪 ORM (PetaPoco),它只将一条 SQL 语句作为字符串并执行它。构建动态查询在 SQL 中的工作方式大致相同 - 大量添加和删除附加代码的条件(平均查询有大约 30 个过滤器)。
所以看了一圈之后,我找到了一些选择:
根据需要添加查询位的一组字符串和条件。真的很讨厌,尤其是当查询变得复杂时,如果存在更好的解决方案,我不想追求。 A bunch of conditionals using L2E。看起来更优雅,但我测试过 L2E 实在是太臃肿了,总体来说是一种糟糕的体验。我可以在 L2S 中做同样的事情吗?如果是这样,L2S 会在未来 5-10 年内持续存在吗? 使用PredicateBuilder。仍在研究这个,关于 L2S 的相同问题。 编辑:我也可以坚持现有的存储过程模型,但无论如何我都必须重写它们,所以看看其他选项不会有什么坏处,因为我仍然需要做腿部工作。还有其他选择吗?任何人都可以对上述任何一种方法有一些经验吗?主要是,您选择的方法是否让您想要构建一台时间机器并为实现它而杀了你?
【问题讨论】:
只是我的两分钱,当 EF4 发布时,我真的很兴奋。现在在过去一年使用它之后,我对臃肿、某些建模场景的复杂性以及生成的 SQL 感到非常不满。我再也不会使用 EF 了——存储过程在顶部一直带有一个精简的 API。不回答你的问题 - 但我想加我两分钱。 从 .Net 3.5 开始,流行的观点认为 L2S 生成的 sql 比 L2E 更高效。我不知道这是否随着 L2E 的更新而改变(包括 .net 4.0 及之后的版本)。在 L2S 中测试相同的条件应该是相当简单的。 您是否考虑过只保留当前的存储过程? @jlnorsworthy - 这当然是一个选项,我应该在上面添加它(我会编辑它)。重要的是,无论我选择什么选项,它们都需要重写(它们非常复杂且速度慢得令人痛苦),所以现在是货比三家看看替代方案是什么样子的好时机。 您能否详细说明“L2E 过于臃肿,总体而言是一种糟糕的体验”? 也许这应该是社区维基?好像不会有具体的答案…… 【参考方案1】:不是真正的答案,但评论太长了:
我使用“连接 SQL 片段”方法构建了一个中型 Web 应用程序,目前正在做类似的工作,但使用 L2E。
我发现通过一些自我控制,concatenate-pices-of-sql 方法并没有那么糟糕。当然使用参数化查询,不要试图将用户输入直接粘贴到 SQL 中。
不过,我一直在慢慢地对 L2E 方法产生欣赏。它为您提供了类型安全性,尽管您确实必须从使用 SQL 的方式“向后”做一些事情——例如 WHERE X IN (...)
构造。但到目前为止,我还没有遇到任何 L2E 无法处理的问题。
我觉得如果其他人大量参与,L2E 方法会更容易维护。
您是否有 L2E 的“膨胀”问题的实际用例?还是只是一种普遍的不适感,您觉得框架在幕后做了太多事情?
一开始我肯定有这种感觉(好吧,现在仍然如此),当然不喜欢阅读生成的 SQL(尤其是与我之前项目中的手写 SQL 相比),但到目前为止,我发现 L2E 与关于仅在实际需要时才访问数据库。
另一个问题是您使用的是什么数据库,以及它的 L2E 绑定的最新程度。如果您使用的是 SQL Server,那么没问题。不过,mysql 可能更不稳定。 L2E 的一大优势在于它与 VStudio 的良好集成,以及 VStudio 自动从您的数据库构建实体模型的能力。不确定对非 MS 数据库后端的支持有多好。
【讨论】:
【参考方案2】:在我看来,L2S 和 L2E 都无法生成高效的 SQL 代码,尤其是在涉及复杂查询时。即使在一些相对简单的情况下,通过两种方法中的任何一种生成查询都会产生低效的 SQL 代码,下面是一个示例:Why does this additional join increase # of queries?
话虽如此,如果您使用的是 SQL Server,L2S 是更好的选择,因为 L2E 旨在处理任何数据库;因为L2E会产生低效的SQL代码。另外要记住的一点是 L2S 或 L2E 都不会利用 tempDB,即生成临时表或表变量或 CTE。
我会重写存储过程,尽可能优化它们,并使用 L2S/L2E 进行简单查询,这将生成到服务器的一次往返(这应该尽可能低),并且确保 SQL Server 使用的执行计划是最有效的(即使用索引等)。
哈桑
【讨论】:
【参考方案3】:我会看看 LLBLGen。它生成的代码非常好并且可定制。他们还提供了一个强大的 linq 提供程序,可以帮助您处理查询。我将它用于几个大型项目并且非常高兴。
http://www.llblgen.com/
【讨论】:
以上是关于动态查询的最佳选择?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Apollo Client 为 React 组件动态设置 GraphQL 查询