Как указать текущий прогресс запроса большого набора данных? - PullRequest
1 голос
/ 27 февраля 2012

Я хочу использовать индикатор выполнения, чтобы показать текущий прогресс,% строк данных были загружены. Я вижу, похожий вопрос задавался в SO, но решение - это просто предложить использование стиля выделения.

Например, я запускаю оператор Select, который запрашивает большую таблицу данных, что может занять несколько секунд. Я хочу, чтобы индикатор выполнения обновлял текущий прогресс запроса. Это возможно?

Я знаю, что есть несколько вещей, которые мне нужны:

  1. Количество записей будет получено. (Может получить сначала по количеству Select (1))
  2. Несколько уведомлений о том, сколько записей я только что получил.

Для 2. это та часть, которую я не знаю, как реализовать.

Я могу подумать о том, чтобы разбить его на запрос пар, но это может быть невозможно все время.

Но как насчет чего-то похожего на Cursor в SQL? Попросите SQL Server запросить чанк и вернуть данные и повторить.

for loop{
    //query a chunk of records

    //return 

    //Next
}

Так что я могу рассчитать прогресс и заполнить их в один DataTable.

Можно ли что-то сделать выше? Если да, то как?

Поскольку я видел приложение ASP.NET, способное показать ход загрузки большой таблицы данных, поэтому я хочу реализовать то же самое в WPF.

Ответы [ 3 ]

2 голосов
/ 27 февраля 2012

Если вы загружаете всю таблицу в память, вы можете сделать это неправильно.Действительно ли пользователю нужны все эти данные?Сколько пользователей будет запрашивать базу данных одновременно?Вы уверены, что пользователь будет работать со всей таблицей?

Если вы ответили да на все эти вопросы, чем вы можете использовать шаблон нумерации страниц: Пропустить + Возьмите и вы сможете повысить прогрессобновить событие с пропуском / взять / общее значение.

//META CODE
var dataTable = new List<DataTable>(); //in-memory storage
int rowCount = [...].Rows.Count(); //this is fast check with database
int current;

while (current < rowCount)
{
  var fetchedData = [...].Skip(current).Take(1000).ToList();
  dataTable.AddRange(fetchedData);
  current = dataTable.Rows.Count();

  //fire progress update event
}
1 голос
/ 27 февраля 2012

Во-первых, вы должны быть уверены, что разбиение запроса на две части не увеличит вдвое ваше время запроса. Вы можете подождать пару секунд, прежде чем получите счет записи, и вы ничего не решили.

Вы могли бы выполнять оба запроса параллельно (базы данных любят параллелизм и очень хорошо справляются с ним), но вы создадите дополнительную нагрузку на базу данных, что может стать проблемой масштабируемости в будущем.

Что касается запросов в чанках, я считаю, что SqlDataReader позволит вам извлекать записи по мере их появления, не дожидаясь завершения всего запроса. Однако вам придется добавить их в таблицу данных самостоятельно.

1 голос
/ 27 февраля 2012

Если вы запросите счетчик текущего набора данных, он будет повторяться по всем строкам. Это почти так же медленно, как просто получить его. Вы можете попытаться выбрать счетчик по выражению sql. например: "SELECT COUNT(ID_COLUMN) FROM TABLE WHERE ...". Это еще один SQL-оператор, который вы должны выполнить, но быстрее, чем запросить у набора данных его счет. Есть C # прогрессбар контроль. Вам просто нужно установить максимальное значение, и каждый раз, когда вы повторяете цикл, вы можете вызывать функцию step (). Это установит индикатор прогресса на один шаг вперед;) Вам не нужно делать процентный расчет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...