【问题标题】:Accessing IEnumerable clears content访问 IEnumerable 会清除内容
【发布时间】:2015-05-10 13:46:24
【问题描述】:

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

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

经过快速调查:读取此数据的任何内容都会完全清除它。即使在调试中,如果我加载“结果视图”以获取数据列表,最初我会看到我的 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

【问题讨论】:

  • 不熟悉 Cassandra 及其连接器,所以不知道为什么要这样做。可能是性能调整,所以查询只执行一次?我不知道它是否适合您,但您是否尝试过实现 IEnumerable?那就是 var data = Data.ToList(),并且可以使用它吗?
  • @Juan 成功了,非常感谢。

标签: c# cassandra ienumerable


【解决方案1】:

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

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

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

现在您无需“清除”即可使用data.Count

【讨论】:

    【解决方案2】:

    不能保证Enumerable 可以被枚举两次。一个正确构建的枚举至少应该抛出一个异常,但错误的代码总是会发生。你可以做的是在一个行为良好的集合中实现它,例如List<T>

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

    现在您甚至拥有 Count 的优势是 O(1) 而不是 O(N) :-)(在 List<T> 中,Count 的值是“缓存的”)

    【讨论】:

    • 谢谢,这很好用。将来我必须牢记 Enumerable 的这一点。谢谢
    猜你喜欢
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 2011-03-05
    • 2016-05-12
    • 2011-05-02
    相关资源
    最近更新 更多