访问 IEnumerable 会清除内容

本文关键字:清除 IEnumerable 访问 | 更新日期: 2024-11-06 21:59:51

我有一个返回IEnumerable的数据库(Cassandra)查询。试图追踪为什么这没有返回数据(当我知道数据库中有数据时),我发现了一个奇怪的问题。

查询实际上返回数据,25 个条目。我正在用数据计数()检查这一点;但在代码的后面,它是空的。我意识到计数方法莫名其妙地清除了数据。

快速调查后:任何读取此数据的内容都会完全清除它。即使在调试中,如果我加载"结果视图"以获取数据列表,最初我会看到我的 25 个条目 - 然后如果我单击关闭,然后重新加载结果视图:Emtpy。

以前有人有过这样的事情吗?

        String connectionString = "SELECT * FROM thedatabase WHERE thecondition";
        RowSet Data = ExecuteComand(connectionString);
        if (Data == null) // interestingly, I can check for null without issue
        {
            OutputMessage("Output to " + exportFile + " failed");
            return;
        }
        int b = Data.Count(); // results in 25
        int c = Data.Count(); // results in 0

访问 IEnumerable 会清除内容

我不知道

cassandra,但我假设返回的IEnumerable<T>是懒惰执行的(延迟)。通过使用它(例如与foreachToListCount),查询被执行并且资源(例如连接)被释放/关闭。

如果是这种情况,您可以将其加载到内存集合中,例如:

var data = ExecuteComand("SELECT * FROM thedatabase WHERE thecondition").ToList();

现在,您可以在不"清除"data.Count的情况下使用它。

不能保证一个Enumerable可以枚举两次。正确构建的可枚举对象至少应该引发异常,但错误代码总是可能发生。您可以做的是将其具体化为一个表现良好的集合,例如List<T>

var data2 = Data.ToList();
int b = data2.Count;
int c = data2.Count;

现在你甚至有优势,Count是O(1)而不是O(N) :-)(在List<T>中,Count值是"缓存")