Ответ 1
У меня была такая же проблема. Я сделал подсказку из вашего блога и разместил предложение ORDER BY в запросе, чтобы они могли сформировать вместе уникальный ключ для всех записей, возвращаемых запросом. Он решил проблему. Что-то странное.
Я пытаюсь заполнить 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);
В какой-то момент я заметил, что отчет был неполным, и в нем отсутствовала одна запись. Я изменил несколько условий, чтобы запрос возвращал ровно две строки и... surprise: в отчете отображается только одна строка вместо двух. Я попытался отладить его, чтобы найти, где проблема, и я застрял в
dt.Load(cmd.ExecuteReader());
Когда я заметил, что DataReader
содержит две записи, но DataTable
содержит только один. Случайно я добавил предложение ORDER BY
к запросу и заметил, что на этот раз отчет показал правильно.
По-видимому, DataReader содержит две строки, но DataTable только считывает их оба, если строка запроса SQL содержит ORDER BY
(в противном случае она только считывает последнюю). Может ли кто-нибудь объяснить, почему это происходит и как это можно исправить?
Edit:
Когда я впервые опубликовал этот вопрос, я сказал, что он пропускает первый ряд; позже я понял, что на самом деле он только читает последнюю строку, и я отредактировал текст соответственно (в то время все записи были сгруппированы в две строки и, похоже, пропустили первый, когда он фактически только показал последний). Это может быть вызвано тем, что у него не было уникального идентификатора, позволяющего отличать строки, возвращаемые MySQL, поэтому добавление оператора ORDER BY
заставило его создать уникальный идентификатор для каждой строки.
Это всего лишь теория, и мне нечего ее поддерживать, но все мои тесты, похоже, приводят к такому же результату.
У меня была такая же проблема. Я сделал подсказку из вашего блога и разместил предложение ORDER BY в запросе, чтобы они могли сформировать вместе уникальный ключ для всех записей, возвращаемых запросом. Он решил проблему. Что-то странное.
вопрос несколько лет, но я не нашел достойного ответа, кроме вышеупомянутого обходного пути.
После небольшого поворота я обнаружил, что метод DataTable.Load ожидает столбца первичного ключа в базовых данных. Если вы внимательно прочитаете документацию, это станет очевидным, хотя это не указано очень четко.
Если у вас есть столбец с именем "id", он, кажется, использует его (который исправил его для меня). В противном случае он просто использует первый столбец, независимо от того, является он уникальным или нет, и перезаписывает строки с тем же значением в этом столбце, когда они читаются. Если у вас нет столбца с именем "id", и ваш первый столбец не является уникальным, я бы предложил попытаться явно установить столбцы первичных ключей для datatable перед загрузкой datareader.
На всякий случай у кого-то есть аналогичная проблема с раковыми, я использовал If DataReader.Read
... вместо If DataReader.HasRows
для проверки существования перед вызовом dt.load(DataReader)
Doh!
Была та же проблема. Это связано с тем, что первичный ключ для всех строк одинаковый. Вероятно, это то, что используется для определения результатов, и поэтому оно снова и снова перезаписывает одну и ту же строку.
Datatables.Load указывает на метод заполнения, чтобы понять, как он работает. На этой странице указано, что это первичный ключ. Поскольку первичные ключи могут встречаться только один раз и используются как клавиши для строки...
"Затем операция Fill добавляет строки в целевые объекты DataTable в DataSet, создавая объекты DataTable, если они еще не существуют. При создании объектов DataTable операция Fill обычно создает только метаданные имени столбца. Однако, если MissingSchemaAction свойство установлено в AddWithKey, соответствующие первичные ключи и ограничения также создаются". (Http://msdn.microsoft.com/en-us/library/zxkb3c3d.aspx)
Не используйте
dr.Read()
Потому что он перемещает указатель на следующую строку. Удалите эту строку, надеюсь, она сработает.
Сегодня столкнулся с этой проблемой.
Ничего в этом потоке не удалось устранить, к сожалению, но затем я завернул свой SQL-запрос в другой оператор SELECT, и он работает!
Например:
SELECT * FROM (
SELECT ..... < YOUR NORMAL SQL STATEMENT HERE />
) allrecords
Странно....
Вы можете захватить фактический запрос, который запущен из профилировщика SQL, и попробовать запустить его? Возможно, это не так, как вы ожидали.
Получается ли такой же результат при использовании SqlDataAdapter.Fill(dataTable)?
Пробовали ли вы поведение команды по-разному? Документы MSDN
Не уверен, почему вам не хватает строки в 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))
Любопытно узнать, все ли это происходит.
Вы пытались позвонить dt.AcceptChanges()
после вызова dt.Load(cmd.ExecuteReader())
, чтобы узнать, помогает ли это?
В моем случае ни ORDER BY, ни dt.AcceptChanges() не работают. Я не знаю, для чего эта проблема. У меня есть 50 записей в базе данных, но в нем всего 49. пропуская первую строку, и если в datareader есть только одна запись, она ничего не показывает.
что за bizzareeee.....
Я знаю, что это старый вопрос, но я столкнулся с одной и той же проблемой, и ни одна из обходных решений, упомянутых здесь, не помогла.
В моем случае использование псевдонима в colum, который используется как PrimaryKey
, решило проблему.
Итак, вместо
SELECT a
, b
FROM table
Я использовал
SELECT a as gurgleurp
, b
FROM table
и он работал.
У меня была такая же проблема.. не использовал dataReader.Read() вообще.. он примет указатель на следующую строку. Вместо этого используйте непосредственно datatable.load(dataReader).
Я знаю, что это старый вопрос, но для меня мысль, которая работала при запросе базы данных доступа, и заметила, что ей не хватает 1 строки из запроса, должно было изменить следующее: -
if(dataset.read()) - Misses a row.
if(dataset.hasrows) - Missing row appears.