我在C#中有一个API,它从数据库和在表格中绘制数据的前端返回数据。
我的方法是使用sqlReader从DB读取数据,遍历此读取器将每个结果添加到列表中并将该列表返回到前端。
似乎很容易,直到我收到大量的查询数据。我的解决方案是按块恢复这个数据块,但我坚持使用它,这是我正在使用的代码:
var sqlCommand = db.InitializeSqlCommand(query);
try
{
using (var reader = sqlCommand.ExecuteReader())
{
var results = new List<List<string>>();
var headers = new List<string>();
var rows = new List<string>();
for (var i = 0; i < reader.FieldCount; i++)
{
headers.Add(reader.GetName(i));
}
results.Add(headers);
while (reader.Read())
{
for (var i = 0; i < reader.FieldCount; i++)
{
rows.Add((reader[reader.GetName(i)]).ToString());
}
results.Add(rows);
var str = JsonConvert.SerializeObject(results);
var buffer = Encoding.UTF8.GetBytes(str);
//Thread.Sleep(1000);
await outputStream.WriteAsync(buffer, 0, buffer.Length);
rows.Clear();
results.Clear();
outputStream.Flush();
}
}
}
catch (HttpException ex)
{
if (ex.ErrorCode == -2147023667) // The remote host closed the connection.
{
}
}
finally
{
outputStream.Close();
db.Dispose();
}
有了这个,我就可以逐个返回数据(用Thread.sleep测试),但我仍然坚持如何返回一个特定的数量,比如200个数据或者1000,这真的不重要。
关于如何进行的任何想法? 提前致谢。 MESE。
答案 0 :(得分:2)
我认为控制查询是更好的方法,因为这将是从数据库中获取的内容。您可以为每次后续运行增加OFFSET
。示例 - 在ORDER BY
子句之后添加OFFSET 200 ROWS FETCH NEXT 200 ROWS ONLY
以跳过200行并获得下一个200.
但是,由于您已经提到您无法控制查询,因此您可以执行类似的操作来过滤我们的结果。这里的关键技巧是使用reader.AsEnumerable.Skip(200).Take(200)
来选择要处理的行。在每次迭代中将输入更新为Skip()
以相应地处理数据。
// Offset variable will decide how many rows to skip, the outer while loop can be
// used to determine if more data is present and increment offset by 200 or any
// other value as required. Offset -> 0, 200, 400, 600, etc.. until data is present
bool hasMoreData = true;
int offset = 0;
while(hasMoreData)
{
// SQL Data reader and other important operations
foreach(var row in reader.AsEnumerable.Skip(offset).Take(200))
{
// Processing operations
}
// Check to ensure there are more rows
if(no more rows)
hasMoreData = false;
offset += 200;
}
另外要记住的是,当您批量提取数据时,查询将多次执行,如果在此期间添加或删除了新记录,则批次将无法正常运行。为了解决这个问题,你可以做两件事:
Skip(0).Take(100)
//拉0到100条记录Skip(90).Take(100)
//拉出90 - 190条记录(重叠10条以满足添加/删除)Skip(180).Take(100)
//拉出180 - 280条记录(重叠10条以满足添加/删除)希望这有帮助!