CodeGo.net>重用LINQ查询导致另一个LINQ查询,而无需重新查询数据库
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了CodeGo.net>重用LINQ查询导致另一个LINQ查询,而无需重新查询数据库,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3250字,纯文字阅读大概需要5分钟。
内容图文
![CodeGo.net>重用LINQ查询导致另一个LINQ查询,而无需重新查询数据库](/upload/InfoBanner/zyjiaocheng/884/23d8dc7dc8aa4acda40cd11e632d60ce.jpg)
我遇到一种情况,我的应用程序根据用户指定的过滤条件使用PredicateBuilder构造了一个动态LINQ查询(此外:请查看此link以获取最佳的EF PredicateBuilder实现).问题是该查询通常需要很长时间才能运行,并且我需要该查询的结果才能执行其他查询(即,将结果与其他表联接).如果正在编写T-SQL,则将第一个查询的结果放入一个临时表或一个表变量中,然后围绕它编写其他查询.我想从第一个查询中获取ID列表(例如List< Int32> query1IDs),然后执行以下操作:
var query2 = DbContext.TableName.Where(x => query1IDs.Contains(x.ID))
这将在理论上起作用;但是,query1ID中的ID数量可以成百上千(而LINQ表达式x => query1IDs.Contains(x.ID)被转换为T-SQL“ IN”语句,这很明显是有原因的) ),并且TableName中的行数为百万.对于解决这种情况的最佳方法,是否有人有任何建议?
编辑1:关于我在做什么的其他说明.
好的,我正在构建第一个查询(query1),它只包含我感兴趣的ID.基本上,我将使用query1来“过滤”其他表.注意:在LINQ语句的末尾,我没有使用ToList()-这时不执行查询,并且没有结果发送到客户端:
var query1 = DbContext.TableName1.Where(ComplexFilterLogic).Select(x => x.ID)
然后,我使用query1并用它来过滤另一个表(TableName2).现在,我将ToList()放在此语句的末尾,因为我想执行它并将结果带给客户端:
var query2 = (from a in DbContext.TableName2 join b in query1 on a.ID equals b.ID select new { b.Column1, b.column2, b.column3,...,b.columnM }).ToList();
然后,我使用query1并重新使用它来过滤另一个表(TableName3),执行它并将结果带给客户端:
var query3 = (from a in DbContext.TableName3 join b in query1 on a.ID equals b.ID select new { b.Column1, b.column2, b.column3,...,b.columnM }).ToList();
我可以继续对任意多个查询执行此操作:
var queryN = (from a in DbContext.TableNameN join b in query1 on a.ID equals b.ID select new { b.Column1, b.column2, b.column3,...,b.columnM }).ToList();
问题:query1需要花费很长时间才能执行.当我执行query2,query3 … queryN时,query1被执行(N-1)次…这不是一种非常有效的处理方式(尤其是因为query1不变).如前所述,如果我正在编写T-SQL,我会将query1的结果放入一个临时表中,然后在后续查询中使用该表.
编辑2:
我将把回答这个问题的功劳归功于Albin Sunnanbo的评论:
When I had similar problems with a heavy query that I wanted to reuse in several other queries I always went back to the solution of creating a join in each query and put more effort in optimizing the query execution (mostly by tweaking my indexes).
我认为这是使用实体框架所能做到的最好的事情.最后,如果性能真的变差,我可能会同意约翰·伍利的建议:
This may be a situation where dropping to native ADO against a stored proc returning multiple results and using an internal temp table might be your best option for this operation. Use EF for the other 90% of your app.
感谢所有对这篇文章发表评论的人…我感谢大家的投入!
解决方法:
如果TableName的大小不太大,无法加载整个表,则使用
var tableNameById = DbContext.TableName.ToDictionary(x => x.ID);
提取整个表格并自动将其放入ID为键的本地Dictionary中.
另一种方法是仅使用.ToList()“强制” LINQ评估,以获取整个表,并使用Linq2Objects在本地进行Where部分.
var query1Lookup = new Hashset<int>(query1IDs);
var query2 = DbContext.TableName.ToList().Where(x => query1IDs.Contains(x.ID));
编辑:
通常可以将一个查询中的一个ID:s列表存储在一个列表中,然后将该列表用作另一个查询中的过滤器,通常可以将其重写为联接.
当我在重查询中遇到类似的问题时,我想在其他几个查询中重用,因此我总是回到在每个查询中创建联接的解决方案,并花更多的精力来优化查询的执行(主要是通过调整索引).
内容总结
以上是互联网集市为您收集整理的CodeGo.net>重用LINQ查询导致另一个LINQ查询,而无需重新查询数据库全部内容,希望文章能够帮你解决CodeGo.net>重用LINQ查询导致另一个LINQ查询,而无需重新查询数据库所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。