我的问题是如何获得通过查询返回的行数SqlDataReader
在C#。 我已经看到了一些有关此答案,但没有除一,指出做while循环进行了明确规定Read()
方法,并增加一个计数器。
我的问题是,我想,以填补之后的是该行数据的第一行是列标题名称,每行中的多维数组。
我知道我可以只转储的东西在一个列表控制,而不用担心它,但我个人的熏陶,我也想拉进出阵列,因为我选择数据并显示它在不同的格式。
所以我觉得我不能这样做Read()
然后递增++的方式,因为这意味着我必须打开Read()
然后打开Read()
再次获得行的金额,然后列数据。
究竟是什么我谈论的一个小例子:
int counter = 0;
while (sqlRead.Read())
{
//get rows
counter++
}
然后一个for循环通过柱和弹出运行
something.Read();
int dbFields = sqlRead.FieldCount;
for (int i = 0; i < dbFields; i++)
{
// do stuff to array
}
只有两种选择:
通过DataReader的循环去两次是真的很贵,你将不得不重新执行查询。
和(感谢皮特OHanlon),当您使用事务与快照隔离级别的第二个选项是唯一的并发安全。
既然你要结束了存储在内存中的所有行反正唯一明智的选择就是读取所有的行以灵活的存储( List<>
或DataTable
),然后将数据复制到任何你想要的格式。 在内存中的操作总是会更有效。
如果您不需要检索所有的行,并希望避免采取一种双重的查询,你也许可以尝试类似的东西:
using (var sqlCon = new SqlConnection("Server=127.0.0.1;Database=MyDb;User Id=Me;Password=glop;"))
{
sqlCon.Open();
var com = sqlCon.CreateCommand();
com.CommandText = "select * from BigTable";
using (var reader = com.ExecuteReader())
{
//here you retrieve what you need
}
com.CommandText = "select @@ROWCOUNT";
var totalRow = com.ExecuteScalar();
sqlCon.Close();
}
您可能需要添加不知道交易是否重复使用相同的命令会自动在其上添加一个交易...
每以上,数据集或类型化的DataSet可能是一个好temorary结构,你可以用做你的过滤。 一个SqlDataReader意味着很快读取数据。 当你在你仍然连接到数据库的while()循环,它正等着你做任何你是为了读/过程的下一个结果它移动之前做的事情。 在这种情况下,如果你在所有的数据拉你可能会得到更好的性能,关闭到数据库的连接,结果“离线”的过程。
人们似乎讨厌的数据集,所以上面的室内用能强类型对象的集合来进行为好。
你不能从一个数据读取器直接获得行的总数,因为它是所谓流水游标 - 这意味着数据被读取基于正在执行的读取逐行基础。 我建议反对这样做2上的数据的读取,因为有数据已做了2间改变了潜在的读取,这样的话你会得到不同的结果。
你可以做的是将数据读入一个临时结构,并用它来代替第二读。 另外,你需要更改您检索数据,并使用像一个DataTable,而不是机制。
完成坑答案和更好的perfromance:让所有在一个查询和使用NextResult方法。
using (var sqlCon = new SqlConnection("Server=127.0.0.1;Database=MyDb;User Id=Me;Password=glop;"))
{
sqlCon.Open();
var com = sqlCon.CreateCommand();
com.CommandText = "select * from BigTable;select @@ROWCOUNT;";
using (var reader = com.ExecuteReader())
{
while(reader.read()){
//iterate code
}
int totalRow = 0 ;
reader.NextResult(); //
if(reader.read()){
totalRow = (int)reader[0];
}
}
sqlCon.Close();
}
我也面对的情况,当我需要回到顶部结果,但也希望得到总行时,即当匹配查询。 我finaly得到此解决方案:
public string Format(SelectQuery selectQuery)
{
string result;
if (string.IsNullOrWhiteSpace(selectQuery.WherePart))
{
result = string.Format(
@"
declare @maxResult int;
set @maxResult = {0};
WITH Total AS
(
SELECT count(*) as [Count] FROM {2}
)
SELECT top (@maxResult) Total.[Count], {1} FROM Total, {2}", m_limit.To, selectQuery.SelectPart, selectQuery.FromPart);
}
else
{
result = string.Format(
@"
declare @maxResult int;
set @maxResult = {0};
WITH Total AS
(
SELECT count(*) as [Count] FROM {2} WHERE {3}
)
SELECT top (@maxResult) Total.[Count], {1} FROM Total, {2} WHERE {3}", m_limit.To, selectQuery.SelectPart, selectQuery.FromPart, selectQuery.WherePart);
}
if (!string.IsNullOrWhiteSpace(selectQuery.OrderPart))
result = string.Format("{0} ORDER BY {1}", result, selectQuery.OrderPart);
return result;
}