通过 DataReader 迭代两次

发布于 2024-09-08 09:25:48 字数 85 浏览 1 评论 0原文

我需要通过 DataReader 迭代两次。有没有一种方法可以在不使用数据集且不运行查询两次的情况下执行此操作?顺便说一句,我正在使用 C#。
谢谢

I need to iterate twice through a DataReader. Is there a way to do this without using DataSets and without running the query twice? I'm using C#, by the way.
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

人生戏 2024-09-15 09:25:48

简短的答案是否定的,您运行结果集的枚举,然后就完成了。可能应该做的是将结果转储为某种简化的原始结果,您可以根据需要迭代它(避免数据集的开销)。

如果您查看 MSDN,它指出 SqlDataReader 是“仅向前”的,这再次表明这是不可能的。

The short answer is no, you run through the enumeration for the result sets and then you're done. What should probably be done is to dump the results to some kind of simplified raw results that you can iterate over as much as you want (avoiding the overhead of the DataSet).

If you take a peek at MSDN, it notes that the SqlDataReader is "forward only" which would suggest again that this isn't possible.

衣神在巴黎 2024-09-15 09:25:48

它是一个只能前进的读者,你不能后退。最好的选择是,不要迭代两次数据读取器,而是在一次迭代中执行您想要执行的两项操作。

您可以自己缓存结果,但这就像破坏了 DataReader 的用途,因此如果您需要多次使用数据,则必须选择其他方式来访问它。

Its a forward-only reader, you cannot go back. Your best bet is that instead of iterating twice the data reader, do both operations you want to do in one iteration.

You can cache the results yourself but that's like destroying the purpose of the DataReader, so if you need to have the data handy many times, you have to choose another way to access it.

jJeQQOZ5 2024-09-15 09:25:48

这是可能的,但不是那么简单,因为数据读取器在每次 Read() 调用时都会发生变化。因此,您需要将以前的值存储在某个地方以便下次访问它。在这里使用数据集并不是一个坏主意。

It is possbile but not so simple, because data reader mutates on each Read() call. So you need to store previous values somewhere to access it next time. Using data set is not so bad idea here.

感悟人生的甜 2024-09-15 09:25:48

IDataReader 规范不允许重置列表,但是请检查特定实现是否也实现了 IEnumerator 或是否具有 GetEnumerator() 函数作为该接口一部分的重置命令。

The IDataReader spec does not allow the list to be reset, however check the specific implementation also implements IEnumerator or has a GetEnumerator() function there is a Reset command as part of that interface.

_蜘蛛 2024-09-15 09:25:48

我有一个解决这个问题的方法,这可能不是最好的,但我使用了很多次,没有出现问题。
您可以在选择子句中创建一个子查询,该子查询将生成要返回的行数。
例子:

SELECT productid, 
  name, 
  price, 
  (SELECT COUNT(*) FROM tblProduct WHERE categoryid=1 AND price <= 1000) 
     AS 'RowCount' 
FROM tblProduct 
WHERE categoryid=1 AND price <= 1000;

I have a solution to this problem, this might not be the best but I used this many times without an issue.
You can create a subquery in the selection clause that will produce how many rows will be returned.
example:

SELECT productid, 
  name, 
  price, 
  (SELECT COUNT(*) FROM tblProduct WHERE categoryid=1 AND price <= 1000) 
     AS 'RowCount' 
FROM tblProduct 
WHERE categoryid=1 AND price <= 1000;
习惯成性 2024-09-15 09:25:48

在游戏后期,但这里有一些代码可以帮助迭代数据集。
老实说,这不是一个数据读取器,而是一个数据集,正如一些人建议的那样。 但您可以迭代数据集两次,或者任意多次:)干杯

…………

        StringBuilder VBAstrBldr = new StringBuilder();
        List<object> objects = new List<object>();
        string destPath = string.Empty;
        string _filePath = string.Empty;
        string timestampSuffix = string.Empty;

    string commandTextDC = @" SELECT  [CategoryID]
                                    ,[AreaNo]
                                    ,[CategoryDesc]
                                    ,[CategoryNo]
                                    ,[CatCodeDisableDate]
                                    ,[CatCodeDeprecateDate]
                            FROM [dbo].[Categories] ";

我只迭代一次

using (var connection = new SqlConnection(_dbLogConn))
{
    connection.Open();
    using (var tran = connection.BeginTransaction())
    {
        using (var command = new SqlCommand(commandTextDC, connection, tran))
        {
            try
            {
                var adapter = new SqlDataAdapter(command);
                DataSet thedataSet = new DataSet();
                adapter.Fill(thedataSet);

                VBAstrBldr.Clear();

                foreach (DataTable table in thedataSet.Tables)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        VBAstrBldr.Append(Environment.NewLine);
                        foreach (DataColumn column in table.Columns)
                        {
                            object item = row[column];
                            // read column and item
                            VBAstrBldr.Append("columnName: " + column.ColumnName.ToString() + " Value: " + item.ToString());
                            VBAstrBldr.Append(Environment.NewLine);
                        }
                    }
                }

                _filePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);
                destPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VBAwithDC" + timestampSuffix + ".txt");

                using (StreamWriter sw = new StreamWriter(System.IO.File.Create(destPath)))
                {
                    sw.Write(VBAstrBldr);
                }
            }
            catch (Exception Ex)
            {
                string msg = Ex.Message.ToString();
                tran.Rollback();
                throw;
            }
        }
    }
}

Late in the game but here is some code to help with iterating through a dataset.
And to be true to the question, this is not a datareader but a dataset instead as some suggested. I'm only iterating once but you can iterate through the dataset twice, or as many times as you like :) Cheers

...

        StringBuilder VBAstrBldr = new StringBuilder();
        List<object> objects = new List<object>();
        string destPath = string.Empty;
        string _filePath = string.Empty;
        string timestampSuffix = string.Empty;

...

    string commandTextDC = @" SELECT  [CategoryID]
                                    ,[AreaNo]
                                    ,[CategoryDesc]
                                    ,[CategoryNo]
                                    ,[CatCodeDisableDate]
                                    ,[CatCodeDeprecateDate]
                            FROM [dbo].[Categories] ";

...

using (var connection = new SqlConnection(_dbLogConn))
{
    connection.Open();
    using (var tran = connection.BeginTransaction())
    {
        using (var command = new SqlCommand(commandTextDC, connection, tran))
        {
            try
            {
                var adapter = new SqlDataAdapter(command);
                DataSet thedataSet = new DataSet();
                adapter.Fill(thedataSet);

                VBAstrBldr.Clear();

                foreach (DataTable table in thedataSet.Tables)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        VBAstrBldr.Append(Environment.NewLine);
                        foreach (DataColumn column in table.Columns)
                        {
                            object item = row[column];
                            // read column and item
                            VBAstrBldr.Append("columnName: " + column.ColumnName.ToString() + " Value: " + item.ToString());
                            VBAstrBldr.Append(Environment.NewLine);
                        }
                    }
                }

                _filePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);
                destPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VBAwithDC" + timestampSuffix + ".txt");

                using (StreamWriter sw = new StreamWriter(System.IO.File.Create(destPath)))
                {
                    sw.Write(VBAstrBldr);
                }
            }
            catch (Exception Ex)
            {
                string msg = Ex.Message.ToString();
                tran.Rollback();
                throw;
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文