Вопрос

Я пытаюсь заполнить DataTable, чтобы создать LocalReport , используя следующее:

MySqlCommand cmd = new MySqlCommand();
cmd.Connection = new MySqlConnection(Properties.Settings.Default.dbConnectionString);
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT ... LEFT JOIN ... WHERE ..."; /* query snipped */

// prepare data
dataTable.Clear();
cn.Open();
// fill datatable
dt.Load(cmd.ExecuteReader());
// fill report
rds = new ReportDataSource("InvoicesDataSet_InvoiceTable",dt);
reportViewerLocal.LocalReport.DataSources.Clear();
reportViewerLocal.LocalReport.DataSources.Add(rds);

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

 dt.Load(cmd.ExecuteReader());

Когда я заметил, что DataReader содержит две записи, но DataTable содержит только один.Случайно я добавил ORDER BY предложение к запросу и заметил, что на этот раз отчет отображен правильно.

По-видимому, DataReader содержит две строки, но DataTable считывает их обе только в том случае, если строка SQL-запроса содержит ORDER BY (в противном случае он читает только последний).Кто-нибудь может объяснить, почему это происходит и как это можно исправить?

Редактировать: Когда я впервые опубликовал вопрос, я сказал, что он пропускает первую строку;позже я понял, что на самом деле он читал только последнюю строку, и я соответствующим образом отредактировал текст (в то время все записи были сгруппированы в две строки, и казалось, что он пропускает первую, хотя на самом деле показывал только последнюю).Это может быть вызвано тем фактом, что у него не было уникального идентификатора, по которому можно было бы различать строки, возвращаемые MySQL, поэтому добавление ORDER BY оператор заставил его создать уникальный идентификатор для каждой строки.
Это всего лишь теория, и мне нечем ее подкрепить, но все мои тесты, похоже, приводят к одному и тому же результату.

Это было полезно?

Решение

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

Другие советы

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

Немного повозившись, я обнаружил, что DataTable.Метод Load ожидает столбец первичного ключа в базовых данных.Если вы внимательно прочтете документацию, это становится очевидным, хотя это и не указано очень явно.

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

На всякий случай, если у кого-то возникла такая же проблема, как canceriens, я использовал If DataReader.Read ...вместо " Если " DataReader.HasRows чтобы проверить наличие перед вызовом dt.load(DataReader) Дох!

Была такая же проблема.Это происходит потому, что первичный ключ во всех строках один и тот же.Вероятно, это то, что используется для обработки результатов, и поэтому это просто перезапись одной и той же строки снова и снова.

Таблицы данных.Загрузка указывает на метод fill, чтобы понять, как он работает.На этой странице указано, что она поддерживает первичный ключ.Поскольку первичные ключи могут встречаться только один раз и используются в качестве ключей для строки ...

"Затем операция заполнения добавляет строки к целевым объектам DataTable в наборе данных, создавая объекты DataTable, если они еще не существуют.При создании объектов, содержащих данные, операция заполнения обычно создает только метаданные имени столбца.Однако, если для свойства MissingSchemaAction установлено значение AddWithKey, также создаются соответствующие первичные ключи и ограничения". (http://msdn.microsoft.com/en-us/library/zxkb3c3d.aspx)

Столкнулся с этой проблемой сегодня.

К сожалению, ничто в этом потоке не исправило это, но затем я завернул свой SQL-запрос в другой оператор SELECT, и это сработало!

Например:

SELECT * FROM (
    SELECT ..... < YOUR NORMAL SQL STATEMENT HERE />
) allrecords

Странно....

Не используйте

dr.Read()

Потому что он перемещает указатель на следующую строку.Удалите эту строку, надеюсь, это сработает.

Можете ли вы получить фактический запрос, который выполняется из SQL profiler, и попробовать запустить его?Возможно, это не то, чего вы ожидали.

Получаете ли вы тот же результат при использовании SqlDataAdapter.Заполнение (DataTable)?

Пробовали ли вы различные варианты командного поведения на считывателе? Документы MSDN

Я знаю, что это старый вопрос, но для меня идея, которая сработала при запросе базы данных access и обнаружении отсутствия 1 строки в запросе, заключалась в изменении следующего:-

    if(dataset.read())  - Misses a row.

    if(dataset.hasrows) - Missing row appears.

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

        Dim deals As New DealsProvider()
        Dim adapter As New ReportingDataTableAdapters.ReportDealsAdapter
        Dim report As ReportingData.ReportDealsDataTable = deals.GetActiveDealsReport()
        rptReports.LocalReport.DataSources.Add(New ReportDataSource("ActiveDeals_Data", report))

Любопытно посмотреть, происходит ли это до сих пор.

В моем случае ни ORDER BY , ни dt.AcceptChanges() не работает.Я не знаю, для чего нужна эта проблема.У меня есть 50 записей в базе данных, но в таблице данных отображается только 49.пропуск первой строки, и если в datareader есть только одна запись, она вообще ничего не показывает.

что за странноеее.....

Ты пробовал звонить dt.AcceptChanges() после того , как dt.Load(cmd.ExecuteReader()) позвоните, чтобы узнать, поможет ли это?

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

В моем случае, используя псевдоним в столбце, который используется в качестве PrimaryKey решил проблему.

Итак, вместо

SELECT a
     , b
FROM table

Я использовал

SELECT a as gurgleurp
     , b
FROM table

и это сработало.

У меня была такая же проблема..вообще не используйте DataReader.Read()..это приведет к указателю на следующую строку.Вместо этого используйте непосредственно datatable.load(DataReader).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top