На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Вывод в dataGrid миллионы строк , Результат SQL-запроса в dataGrid C# WPF
    Уважаемые подскажите как можно вывести 100 - 500 млн. строк в dataGrid проект C#WPF в WPF/
    Если кто знает помогите или кодом кто сколько может, или хоть сылочкой вразумительной
      Этого делать не нужно. Кто способен просмотреть сто миллионов записей?
      И вообще данные в контролах хранить не нужно (разве что десятки строк для мелких задач)

      Познакомься с концепцией виртуального режима (virtual mode)
      Сообщение отредактировано: MBo -
        Цитата MBo @
        И вообще данные в контролах хранить не нужно

        не не надо надо , я их не хранить собираюсь , а визуализация супер больших объемов даннных
        ты SQL-запрос к БД делаешь , а в ответ прилетает окошко извините тут много данных мы их Вам не покажем :)
        сколько их там не было бы их надо показать на дворе 22век
        это один из методо виртуализация

        Добавлено
        другое дела кто сталкивался с выводом , в теории я немного нашел пару проектов , но там тяжковато
        https://www.codeproject.com/Articles/34405/...-Virtualization

        Добавлено
        теорию читаю пробую делать , привязать к своему проекту , но вот даже вразумительно не могу поделить на пачки

        тоесть , алгоритм подскажите какой нибудь на пальцах
        у меня это вот так
        ExpandedWrap disabled
          ...
            . .. .
          for (int gStart = 0; gStart < Кол-воПакетов; gStart++)  
           {
           
            err = ф-цияВычитываемРезультат(); // Чтение результатов
                for(проход по Пакету )
                {
                      .....
          . . .

        как то так
          шо опять?! :D
            Цитата kms @
            другое дела кто сталкивался с выводом , в теории я немного нашел пару проектов , но там тяжковато


            hcSqlReadResults, судя по всему, позволяет вычитывать не все данные, а только часть, которая задаётся параметрами gStart и wBufSize. Надо только проверить, действительно ли это работает.
            Если работает, то в свою очередь, в стандартном виндовском ListView есть возможность не добавлять все строки, а возвращать нужные данные по запросу - Virtual List-View Style, LVS_OWNERDATA, LVN_GETDISPINFO.
            Думаю, эта схема вполне работает и в C#.
              Месье просто не в курсе о возможности обработки скролла. В школу.

              Добавлено
              Цитата kms @
              а визуализация супер больших объемов даннных

              Визуализатор блин, ни один нормальный разраб не будет гонять многогигабайты, м/у клиентом и серваком БД, так поступают только долбаебы.
                Цитата Gonarh @
                Визуализатор блин, ни один нормальный разраб не будет гонять многогигабайты, м/у клиентом и серваком БД, так поступают только долбаебы

                А что он, нормальный разработчик, будет с ними делать?
                  Цитата Cfon @
                  шо опять?!

                  да , я же писал что вопрос буду обкатывать все стороне и глубоко

                  Добавлено
                  Цитата Олег М @
                  hcSqlReadResults, судя по всему, позволяет вычитывать не все данные, а только часть, которая задаётся параметрами gStart и wBufSize.

                  да вычитывает не все а только сколько влазит в буфер,
                  ExpandedWrap disabled
                    hcERR hcSqlReadResults(
                      hcHSTMT   h,      /* Оператор с результатами */
                      hcRECNO   gStart,     /* С какой записи начинаем читать */
                      void      *pBuf,
                      unsigned  wBufSize,
                      unsigned  *cnt)       /* Сколько прочитали */
                    Параметры:
                     
                    ТипАргументЗначение
                    hcHSTMT h   Идентификатор оператора, содержащего результаты поиска оператором select.
                    hcRECNO gStart  Номер записи в результате, начиная с которой пересылаются результаты. Все найденные записи нумеруются с 0.
                    void *  pBuf    Адрес буфера для присылаемых записей.
                    unsigned    wBufSize    Размер буфера для результатов. В буфер помещается целое количество записей. Если запись не может войти в буфер целиком, она не присылается.
                    unsigned *  cnt Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются.


                  Добавлено
                  Цитата Олег М @
                  Надо только проверить, действительно ли это работает.

                  да это работает проверял
                    пробую так
                    ExpandedWrap disabled
                      ..  .  
                              . ... .
                      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 Кбайт, скачиваний: 535)

                    вот такая ошибка во время выполнения на этой строке
                    ExpandedWrap disabled
                      case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной
                           std::string s(p, infCol[j].len);      std::cout << s.c_str() << "  "; }
                               break;



                    Добавлено
                    Цитата Олег М @
                    Думаю, эта схема вполне работает и в C#.

                    да в С# особенно в C#WPF там есть всякие плюшки, но я хочу обкатать пока на С++, чтобы изучить понять
                    Сообщение отредактировано: kms -
                      вот как то так , работает
                      ExpandedWrap disabled
                        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;
                                }
                            }


                      Добавлено
                      но прошу вашей помощи в оптимизации этого алгоритма , а то че то мне кажется тут лишние ифы

                      Добавлено
                      теперь осталось повесить на скролинг эти пачки
                        Цитата kms @
                        int remPakStr  = pStr % razPak ; // остаток строк которые не влезли в пачку, если > 0 , то последняя пачка не полная и надо что то делать

                        Остаток вычислять не нужно, hcSqlReadResults тебе возвращает количество выбранных данных, в cntOut.
                        ExpandedWrap disabled
                              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++)// цикл по кол-ву пачек

                        Добавлено
                        А вообще всю эту бадягу лучше завернуть в функцию, что-то типа
                        ExpandedWrap disabled
                          std::list<std::unique_ptr<CRecord>> FetchRecords(hcHSTMT h, hcRECNO gStart, size_t Count)
                          {
                          .................................................
                          }
                          Олег М а можно буфер объявить до цикла , на каждой итерации пользоваться а потом после цикла уже убить его
                            Цитата kms @
                            Олег М а можно буфер объявить до цикла , на каждой итерации пользоваться а потом после цикла уже убить его

                            Можно
                              делаю
                              ExpandedWrap disabled
                                std::unique_ptr<char[]> bufOut(new char[setRazBuf]);


                              пишет ошибку
                              ExpandedWrap disabled
                                 
                                Ошибка (активно)не существует подходящей функции преобразования из "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) и останавливается

                              Добавлено
                              ExpandedWrap disabled
                                 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;
                                        }
                                    }
                                Цитата kms @
                                сделал все по Вашей схеме выводит 52 строки (всего 130) и останавливается

                                Естественно. Вот это что - gStart * 50? Здесь надо просто gStart

                                Добавлено
                                Цитата Олег М @
                                char *p = bufOut; // указатель на буфер

                                Это не нужно

                                Добавлено
                                Цитата kms @
                                pRecSize * razPak

                                Вместо этого поставь setRazBuf

                                Добавлено
                                И проверяй err
                                  извиняюсь ровно 50 строк выводит
                                    Цитата kms @
                                    извиняюсь ровно 50 строк выводит

                                    Причину понял?
                                      Цитата Олег М @
                                      Цитата kms @ 13 минут назад
                                      сделал все по Вашей схеме выводит 52 строки (всего 130) и останавливается

                                      Естественно. Вот это что - gStart * 50? Здесь надо просто gStart

                                      Добавлено 2 минуты назад
                                      Цитата Олег М @ 3 минуты назад
                                      char *p = bufOut; // указатель на буфер

                                      Это не нужно

                                      Добавлено 1 минуту назад
                                      Цитата kms @ 13 минут назад
                                      pRecSize * razPak

                                      Вместо этого поставь setRazBuf

                                      Добавлено 1 минуту назад
                                      И проверяй err


                                      все сделал , даже работать стало быстрей , до этого я успевал глазом моргнуть а сейчас не успеваю , класс

                                      Добавлено
                                      Цитата Олег М @
                                      Причину понял?

                                      да понял

                                      Добавлено
                                      теперьбы как бы эти пачки связать хоть даже в С++ со скролингом

                                      Добавлено
                                      а ну да вот Вы говорили еще можно в функцию вынести , точно
                                      щас попробую

                                      Добавлено
                                      Сделал по рабоче крестьянски
                                      ExpandedWrap disabled
                                        int FetchRecords(int pOper , hcSqlDstInfoT *infCol , unsigned pRecSize  , unsigned  cntOut, int pCol)
                                        {
                                            int err;
                                            int razPak = 50; // размер пачкиСтрок
                                         
                                            int setRazBuf = pRecSize * razPak; // устанавливаем размер буфера
                                         
                                            char *bufOut = new char[setRazBuf]; // делаем буфер размером на 1 пачку
                                         
                                            for (int gStart = 0; ; gStart += razPak) //  цикл по кол-ву пачек
                                            {
                                         
                                          if (err = hcSqlReadResults(pOper, gStart, bufOut, setRazBuf, &cntOut) != 0) break;//Чтение результатов
                                         
                                                for (char *p = bufOut, *end = p + cntOut; p < end; )//  перебираем строки в пачке
                                                {
                                                    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;
                                                }
                                         
                                                if (cntOut < setRazBuf) break;
                                         
                                            }
                                          
                                            return 0;
                                        }


                                      ну зато хоть удобней смотреть
                                        Цитата kms @
                                        Сделал по рабоче крестьянски

                                        И что ты планируешь с ней делать? Тебе нужно чтобы она как-то данные возвращала, для последующей обработки.

                                        Цитата kms @

                                            char *bufOut = new char[setRazBuf]; // делаем буфер размером на 1 пачку

                                        Буфер ты так и не удаляешь
                                          Цитата Олег М @
                                          И что ты планируешь с ней делать? Тебе нужно чтобы она как-то данные возвращала, для последующей обработки.

                                          да , чето я уже загнался , сегодня уже спать хочу , завтрадоделаю отпишусь

                                          Добавлено
                                          Цитата Олег М @
                                          Буфер ты так и не удаляешь

                                          забыл , уже поправил
                                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                          0 пользователей:


                                          Рейтинг@Mail.ru
                                          [ Script execution time: 0,0733 ]   [ 19 queries used ]   [ Generated: 29.03.24, 12:45 GMT ]