Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.216.186.164] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Уважаемые подскажите как можно вывести 100 - 500 млн. строк в dataGrid проект C#WPF в WPF/
Если кто знает помогите или кодом кто сколько может, или хоть сылочкой вразумительной |
Сообщ.
#2
,
|
|
|
Этого делать не нужно. Кто способен просмотреть сто миллионов записей?
И вообще данные в контролах хранить не нужно (разве что десятки строк для мелких задач) Познакомься с концепцией виртуального режима (virtual mode) |
Сообщ.
#3
,
|
|
|
Цитата MBo @ И вообще данные в контролах хранить не нужно не не надо надо , я их не хранить собираюсь , а визуализация супер больших объемов даннных ты SQL-запрос к БД делаешь , а в ответ прилетает окошко извините тут много данных мы их Вам не покажем сколько их там не было бы их надо показать на дворе 22век это один из методо виртуализация Добавлено другое дела кто сталкивался с выводом , в теории я немного нашел пару проектов , но там тяжковато https://www.codeproject.com/Articles/34405/...-Virtualization Добавлено теорию читаю пробую делать , привязать к своему проекту , но вот даже вразумительно не могу поделить на пачки тоесть , алгоритм подскажите какой нибудь на пальцах у меня это вот так ... . .. . for (int gStart = 0; gStart < Кол-воПакетов; gStart++) { err = ф-цияВычитываемРезультат(); // Чтение результатов for(проход по Пакету ) { ..... . . . как то так |
Сообщ.
#4
,
|
|
|
шо опять?!
|
Сообщ.
#5
,
|
|
|
Цитата kms @ другое дела кто сталкивался с выводом , в теории я немного нашел пару проектов , но там тяжковато hcSqlReadResults, судя по всему, позволяет вычитывать не все данные, а только часть, которая задаётся параметрами gStart и wBufSize. Надо только проверить, действительно ли это работает. Если работает, то в свою очередь, в стандартном виндовском ListView есть возможность не добавлять все строки, а возвращать нужные данные по запросу - Virtual List-View Style, LVS_OWNERDATA, LVN_GETDISPINFO. Думаю, эта схема вполне работает и в C#. |
Сообщ.
#6
,
|
|
|
Месье просто не в курсе о возможности обработки скролла. В школу.
Добавлено Цитата kms @ а визуализация супер больших объемов даннных Визуализатор блин, ни один нормальный разраб не будет гонять многогигабайты, м/у клиентом и серваком БД, так поступают только долбаебы. |
Сообщ.
#7
,
|
|
|
Цитата Gonarh @ Визуализатор блин, ни один нормальный разраб не будет гонять многогигабайты, м/у клиентом и серваком БД, так поступают только долбаебы А что он, нормальный разработчик, будет с ними делать? |
Сообщ.
#8
,
|
|
|
Цитата Cfon @ шо опять?! да , я же писал что вопрос буду обкатывать все стороне и глубоко Добавлено Цитата Олег М @ hcSqlReadResults, судя по всему, позволяет вычитывать не все данные, а только часть, которая задаётся параметрами gStart и wBufSize. да вычитывает не все а только сколько влазит в буфер, hcERR hcSqlReadResults( hcHSTMT h, /* Оператор с результатами */ hcRECNO gStart, /* С какой записи начинаем читать */ void *pBuf, unsigned wBufSize, unsigned *cnt) /* Сколько прочитали */ Параметры: ТипАргументЗначение hcHSTMT h Идентификатор оператора, содержащего результаты поиска оператором select. hcRECNO gStart Номер записи в результате, начиная с которой пересылаются результаты. Все найденные записи нумеруются с 0. void * pBuf Адрес буфера для присылаемых записей. unsigned wBufSize Размер буфера для результатов. В буфер помещается целое количество записей. Если запись не может войти в буфер целиком, она не присылается. unsigned * cnt Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. Добавлено Цитата Олег М @ Надо только проверить, действительно ли это работает. да это работает проверял |
Сообщ.
#9
,
|
|
|
пробую так
.. . . ... . int pakStr = pStr / 50; // делим все количество строк на пачки по 50строк for (int gStart = 0; gStart < pakStr; gStart++) { char *bufOut = new char[pRecSize * 50]; // Адрес буфера для присылаемых записей делаем на 50строк чтобы больше не лезло. err = hcSqlReadResults(pOper, 0, bufOut, pRecSize * 50, &cntOut); // Чтение результатов char *p = bufOut; // делаем указатель на массив for (long i = 0; i < pStr; i++)//идем по строкам { for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type) { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной std::string s(p, infCol[j].len); std::cout << s.c_str() << " "; } break; .... .. .. .. . это конечно же должно отработать не до конца правильно, так как всегда будет остаток от деления на 50 Прикреплённый файл111.png (28,03 Кбайт, скачиваний: 537) вот такая ошибка во время выполнения на этой строке case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной std::string s(p, infCol[j].len); std::cout << s.c_str() << " "; } break; Добавлено Цитата Олег М @ Думаю, эта схема вполне работает и в C#. да в С# особенно в C#WPF там есть всякие плюшки, но я хочу обкатать пока на С++, чтобы изучить понять |
Сообщ.
#10
,
|
|
|
вот как то так , работает
int razPak = 50; // размер пачкиСтрок int remPakStr = pStr % razPak ; // остаток строк которые не влезли в пачку, если > 0 , то последняя пачка не полная и надо что то делать int pakStrok = pStr / razPak ; // кол-во пачекСтрок if (remPakStr != 0 || pStr < 50 ) pakStrok++ ; int setRazBuf = pRecSize * razPak; // устанавливаем размер буфера for(int gStart = 0; gStart < pakStrok ; gStart++)// цикл по кол-ву пачек { if ( (pakStrok-1) == gStart ) razPak = remPakStr; char *bufOut = new char[setRazBuf]; // делаем буфер размером на 1 пачку err = hcSqlReadResults(pOper, gStart * 50, bufOut, pRecSize * razPak, &cntOut); // Чтение результатов char *p = bufOut; // указатель на буфер for (int i = 0; i < razPak; i++) // перебираем строки в пачке { for (int j = 0; j < pCol; j++) // перебираем колонки { switch (infCol[j].type) { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной std::string s(p, infCol[j].len); std::cout << s.c_str() << " "; } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины std::cout << *reinterpret_cast<unsigned char *>(p) << " "; break; case HSCLI_ET_BYTE: // 2 Элемент - unsigned char (короткое целое) short std::cout << *reinterpret_cast<unsigned char *>(p) << " "; break; case HSCLI_ET_INTR: // 3 Элемент - signed short std::cout << *reinterpret_cast<signed short *>(p) << " "; break; case HSCLI_ET_WORD: // 4 Элемент - unsigned short std::cout << *reinterpret_cast<unsigned short *>(p) << " "; break; case HSCLI_ET_DATE: // 5 Дата - unsigned short std::cout << *reinterpret_cast<unsigned short *>(p) << " "; break; case HSCLI_ET_NMBR: //6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); break; case HSCLI_ET_LONG: //7 Элемент - long int std::cout << *reinterpret_cast<long int *>(p) << " "; break; case HSCLI_ET_DWRD: // 8 Элемент - unsigned long int в БД это dword std::cout << *reinterpret_cast<unsigned long int *>(p) << " "; break; case HSCLI_ET_FLOA: // 9 Элемент - float std::cout << *reinterpret_cast<float *>(p) << " "; break; case HSCLI_ET_CURR: // 10 Деньги (double) std::cout << *reinterpret_cast<double *>(p) << " "; break; case HSCLI_ET_DFLT: // 11 Элемент - double std::cout << *reinterpret_cast<double *>(p) << " "; break; case HSCLI_ET_QINT: // 12 Элемент - signed __int64 std::cout << *reinterpret_cast<signed __int64 *>(p) << " "; break; case HSCLI_ET_QWRD: // 13 Элемент - unsigned __int64 std::cout << *reinterpret_cast<unsigned __int64 *>(p) << " "; break; } p += infCol[j].len; } std::cout << std::endl; } } Добавлено но прошу вашей помощи в оптимизации этого алгоритма , а то че то мне кажется тут лишние ифы Добавлено теперь осталось повесить на скролинг эти пачки |
Сообщ.
#11
,
|
|
|
Цитата kms @ int remPakStr = pStr % razPak ; // остаток строк которые не влезли в пачку, если > 0 , то последняя пачка не полная и надо что то делать Остаток вычислять не нужно, hcSqlReadResults тебе возвращает количество выбранных данных, в cntOut. for(int gStart = 0; ; gStart += razPak)// цикл по кол-ву пачек { std::unique_ptr<char[]> bufOut(new char[setRazBuf]); // делаем буфер размером на 1 пачку err = hcSqlReadResults(pOper, gStart, bufOut, pRecSize * razPak, &cntOut); // Чтение результатов if (err != 0) break; for (char *p = bufOut, *end = p + cntOut; p < end; ) // перебираем строки в пачке { for (int j = 0; j < pCol; j++) // перебираем колонки { switch (infCol[j].type) { ........................................... } p += infCol[j].len; } } if (cntOut < setRazBuf) break; } Добавлено Цитата kms @ char *bufOut = new char[setRazBuf]; // делаем буфер размером на 1 пачку Ты его не удаляешь. Либо сделай std::unique_ptr<char[]> bufOut(new char[setRazBuf]), либо в конце цикла делай delete[] bufOut. Лучше первое. Добавлено А вообще его можно выделить один раз до цикла for(int gStart = 0; gStart < pakStrok ; gStart++)// цикл по кол-ву пачек Добавлено А вообще всю эту бадягу лучше завернуть в функцию, что-то типа std::list<std::unique_ptr<CRecord>> FetchRecords(hcHSTMT h, hcRECNO gStart, size_t Count) { ................................................. } |
Сообщ.
#12
,
|
|
|
Олег М а можно буфер объявить до цикла , на каждой итерации пользоваться а потом после цикла уже убить его
|
Сообщ.
#13
,
|
|
|
Цитата kms @ Олег М а можно буфер объявить до цикла , на каждой итерации пользоваться а потом после цикла уже убить его Можно |
Сообщ.
#14
,
|
|
|
делаю
std::unique_ptr<char[]> bufOut(new char[setRazBuf]); пишет ошибку Ошибка (активно)не существует подходящей функции преобразования из "std::unique_ptr<char [], std::default_delete<char []>>" в "void *"AdmHyTechd:\__My_PROJ_HyTech\!_My_Soft_HyTech_!\1_HyTech_консоль(2)\AdmHyTech\main.cpp61 Ошибка (активно)не существует подходящей функции преобразования из "std::unique_ptr<char [], std::default_delete<char []>>" в "char *"AdmHyTechd:\__My_PROJ_HyTech\!_My_Soft_HyTech_!\1_HyTech_консоль(2)\AdmHyTech\main.cpp62 ОшибкаC2440инициализация: невозможно преобразовать "std::unique_ptr<char [],std::default_delete<_Ty>>" в "char *"AdmHyTechd:\__my_proj_hytech\!_my_soft_hytech_!\1_hytech_консоль(2)\admhytech\main.cpp62 ОшибкаC2664"hcERR hcSqlReadResults(hcHSTMT,hcRECNO,void *,unsigned int,unsigned int *)": невозможно преобразовать аргумент 3 из "std::unique_ptr<char [],std::default_delete<_Ty>>" в "void *"AdmHyTechd:\__my_proj_hytech\!_my_soft_hytech_!\1_hytech_консоль(2)\admhytech\main.cpp61 Добавлено Цитата Олег М @ Можно ОК уже сделал Добавлено Олег М сделал все по Вашей схеме выводит 52 строки (всего 130) и останавливается Добавлено int razPak = 50; // размер пачкиСтрок int setRazBuf = pRecSize * razPak; // устанавливаем размер буфера char *bufOut = new char[setRazBuf]; // делаем буфер размером на 1 пачку for (int gStart = 0; ; gStart += razPak) // цикл по кол-ву пачек { err = hcSqlReadResults(pOper, gStart * 50, bufOut, pRecSize * razPak, &cntOut); // Чтение результатов char *p = bufOut; // указатель на буфер for (char *p = bufOut, *end = p + cntOut; p < end; )// // перебираем строки в пачке { for (int j = 0; j < pCol; j++) // перебираем колонки { switch (infCol[j].type) { ....... } p += infCol[j].len; } std::cout << std::endl; } } |
Сообщ.
#15
,
|
|
|
Цитата kms @ сделал все по Вашей схеме выводит 52 строки (всего 130) и останавливается Естественно. Вот это что - gStart * 50? Здесь надо просто gStart Добавлено Цитата Олег М @ char *p = bufOut; // указатель на буфер Это не нужно Добавлено Цитата kms @ pRecSize * razPak Вместо этого поставь setRazBuf Добавлено И проверяй err |