我使用以下两种方法查询数据库并将结果推送到控制台和文件:
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
在这两个调用中,结果都在 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/