c# - 使用 sql linq 查询的结果导致数据库被查询两次

标签 c# linq-to-sql

我使用以下两种方法查询数据库并将结果推送到控制台和文件:

var result = from p in _db.Pages
             join r in rank on p.PkId equals r.Key
             orderby r.NumPages descending
             select new KeyNameCount
                                    {
                                        PageID = p.PkId,
                                        PageName = p.Name,
                                        Count = r.NumPages
                                    };

WriteFindingsToFile(result, parentId);
WriteFindingsToConsole(result, parentId);

当在两个方法调用中用作参数时,IEnumerable,而不是 IQuerable 用作结果的参数类型。

在这两个调用中,结果都在 foreach 中迭代。这会导致对数据库进行两次相同的调用,每种方法调用一次。

我可以将这两种方法重构为一种并且只使用一种 foreach,但这很快就会变得非常难以维护(添加写入 html、写入 xml 等)

我很确定这是一个非常普遍的问题,但是使用谷歌并没有让我变得更聪明,所以我求助于你们:-)

最佳答案

每次访问 LINQ 查询时,它都会重新查询数据库以刷新数据。要阻止这种情况发生,请使用 .ToArray().ToList().
例如

var result = (from p in _db.Pages
             select p).ToList(); //will query now

Write(result);  //will not requery
Write(result2); //will not requery

重要的是要了解原始 LINQ 查询在使用时运行,而不是在编写代码时运行(例如,在此之前不要处理 _db)。

当你意识到它是如何工作的时,你可能会感到惊讶。这允许方法链接和查询的稍后修改反射(reflect)在数据库上运行的最终查询中。始终牢记这一点很重要,因为它可能会导致在编译时无法捕获的运行时错误,通常是因为在使用列表之前数据库连接已关闭,因为您正在传递看似简单的 IEnumerable .

编辑:更改为删除我的意见并在评论中反射(reflect)讨论。我个人认为编译器应该假设链式查询的最终结果会立即运行,除非您明确表示稍后将对其进行进一步修改。只是为了避免它不可避免地导致的运行时错误。

关于c# - 使用 sql linq 查询的结果导致数据库被查询两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8603811/

相关文章:

c# - 延迟执行 - 字典输出

c# - 如何使用 LINQ to SQL 创建通用数据访问对象 (DAO) CRUD 方法

c# - T4 工具箱 Linq2Sql

c# - StreamType 已弃用。如何获取流类型?

c# - 如何获得最佳数字格式字符串?

c# - .NET Native 比使用 ReadAsync 调用的调试构建慢得多

c# - 为什么我的 SQL 查询返回重复的结果?

c# - pdf呈现到asp.net网页导致静态标题

.net - 编辑 WCF 服务自动生成的 DMBL 文件

c# - 从 LINQ to SQL 获取 SQL 查询?