2008-10-23 7 views
17

Estoy intentando rellenar un DataTable, para construir un LocalReport, utilizando la siguiente:
.NET DataTable salta filas de Carga (DataReader)

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); 

En un momento me di cuenta de que el informe era incompleta y faltaba un registro. He cambiado algunas condiciones para que la consulta devuelva exactamente dos filas y ... sorpresa: el informe muestra solo una fila en lugar de dos. He tratado de depurarlo para encontrar dónde está el problema y me quedé atrapado en

dt.Load(cmd.ExecuteReader()); 

Cuando me he dado cuenta de que el DataReader contiene dos registros, pero el DataTable contiene sólo una. Por accidente, agregué una cláusula ORDER BY a la consulta y me di cuenta de que esta vez el informe se mostraba correctamente.

Aparentemente, el DataReader contiene dos filas, pero DataTable solo las lee a ambas si la cadena de consulta SQL contiene un ORDER BY (de lo contrario, solo lee el último). ¿Alguien puede explicar por qué está sucediendo esto y cómo se puede solucionar?

Edit: Cuando primero publiqué la pregunta, dije que se saltaba la primera fila; más tarde me di cuenta de que solo leía la última fila y edité el texto en consecuencia (en ese momento todos los registros estaban agrupados en dos filas y parecía omitir el primero cuando en realidad solo mostraba el último). Esto puede deberse al hecho de que no tenía un identificador único para distinguir entre las filas devueltas por MySQL, por lo que al agregar la declaración ORDER BY se creó un identificador único para cada fila.
Esto es solo una teoría y no tengo nada que lo respalde, pero todas mis pruebas parecen conducir al mismo resultado.

+2

Mod + 1 porque he estado programando .NET y ADO.NET todos los días desde las primeras versiones beta y nunca supe que podría simplemente llamar a dt.Load() sin un DataAdapter. Suspiro. –

+1

Situación similar aquí, Dave. Me enteré hace solo un mes. –

+0

Hoy he publicado una pregunta duplicada (https://stackoverflow.com/questions/28676382/datatable-load-shows-less-rows-than-source-datareader) que finalmente se resolvió al ajustar la consulta. Quiero resaltar que esto ** solo ** ocurre en MYSQL. No ocurre en SQLSERVER. Creo que el problema no debe ser causado por el componente DataTable, sino que podría ser un error en el conector Mysql. ¿Alguna idea? –

Respuesta

2

Tuve el mismo problema. Tomé una pista de su blog y puse la cláusula ORDER BY en la consulta para que pudieran formar juntas la clave única para todos los registros devueltos por la consulta. Solucionó el problema. Algo raro.

+0

Estoy experimentando esto. Ya tengo un pedido POR – Rhyous

1

¿Puede obtener la consulta real que se está ejecutando desde el generador de perfiles SQL e intentar ejecutarla? Puede que no sea lo que esperabas.

¿Obtiene el mismo resultado al usar un SqlDataAdapter.Fill (dataTable)?

¿Has probado diferentes comportamientos de comando en el lector? MSDN Docs

+0

Sí, he intentado ejecutar las consultas en un cliente MySQL. La única diferencia entre ellos es que uno tiene ORDER BY Invoice.ID y el otro no, ambos devuelven dos filas en el mismo orden. Voy a verificar SqlDataAdapter ahora. – Tom

+0

¿Alguna suerte? Por casualidad no tienes un TOP en la consulta, ¿verdad? – StingyJack

+1

El uso de un SqlDataAdapter funcionó para mí. – Rhyous

0

No estoy seguro de por qué te falta la fila en la tabla de datos, ¿es posible que necesites cerrar el lector? En cualquier caso, así es como normalmente cargo los informes y funciona todo el tiempo ...

 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)) 

Es curioso ver si todavía sucede.

0

¿Ha intentado llamar al dt.AcceptChanges() después de la llamada dt.Load(cmd.ExecuteReader()) para ver si eso ayuda?

+0

No se realizan modificaciones. – Tom

0

En mi caso, ni ORDER BY ni dt.AcceptChanges() están funcionando. No sé por qué es ese problema. Tengo 50 registros en la base de datos, pero solo muestra 49 en la tabla de datos. omitiendo la primera fila, y si solo hay un registro en el lector de datos, no muestra nada en absoluto.

qué bizzareeee .....

+1

La próxima vez, publíquelo como comentario o en forma de pregunta. Esto no es aceptable como respuesta en StackOverflow. – Tom

+0

Él tiene 1 punto y no tiene suficiente punto para comentar (al menos 50) – qnguyen

3

Sólo en caso de que alguien está teniendo un problema similar como canceriens, yo estaba usando Si DataReader.Read ... Si en lugar de DataReader.HasRows para comprobar la existencia antes de llamar dt.load(DataReader) Doh!

5

la pregunta tiene varios años, pero no encontré una respuesta decente, aparte de la solución anterior.

Después de juguetear un poco encontré que el método DataTable.Load espera una columna de clave primaria en los datos subyacentes. Si lee la documentación detenidamente, esto se vuelve obvio, aunque no se menciona de manera muy explícita.

Si tiene una columna llamada "id", parece usar eso (que me lo arregló). De lo contrario, parece que solo utiliza la primera columna, ya sea única o no, y sobrescribe las filas con el mismo valor en esa columna a medida que se leen. Si no tiene una columna llamada "id" y su primera columna no es única, le sugiero que intente establecer explícitamente la (s) columna (s) de clave principal de la tabla de datos antes de cargar el lector de datos.

+0

Agregué una columna de ID en vano. – Rhyous

+0

Esta respuesta solucionó mi problema – chriszumberge

3

Tenía el mismo problema. Es porque la clave principal en todas las filas es la misma. Probablemente sea lo que se está utilizando para clavear los resultados, y por lo tanto, solo sobrescribe la misma fila una y otra vez.

Datatables.Load apunta al método de relleno para comprender cómo funciona. Esta página indica que es consciente de la clave primaria. Dado que las claves primarias solo pueden aparecer una vez y se utilizan como claves para la fila ...

"La operación Rellenar agrega las filas a los objetos DataTable de destino en el conjunto de datos, creando los objetos DataTable si aún no existen. Al crear objetos DataTable, la operación Rellenar normalmente solo crea metadatos de nombre de columna. Sin embargo, si la propiedad MissingSchemaAction se establece en AddWithKey, también se crean las principales claves primarias y las restricciones. " (Http://msdn.microsoft.com/en-us/library/zxkb3c3d.aspx)

+0

Podría no solo afectar a la clave principal. Si la clave principal no está en los resultados, puede marcar otra columna. – Bluebaron

+0

Volví a verificar, solo para estar seguro. Absolutamente. El lector devuelve 5 filas, pero dt.Load solo le proporciona la última fila del lector. Solo para que sepan que no estaba diciendo mi trasero. Creo que esta es la primera vez que alguien en realidad apuntó este. ¡Comprueba, por favor! :) – Bluebaron

2

No utilice

dr.Read() 

porque se mueve el puntero a la siguiente fila. Eliminar esta línea espero que funcione.

0

Sé que esta es una pregunta anterior, pero estaba teniendo el mismo problema y ninguna de las soluciones mencionadas aquí me ayudó.

En mi caso, usar un alias en la columna que se usa como PrimaryKey resolvió el problema.

Así, en lugar de

SELECT a 
    , b 
FROM table 

Solía ​​

SELECT a as gurgleurp 
    , b 
FROM table 

y funcionó.

2

Encontré hoy este problema.

¡Nada en este hilo lo arregló por desgracia, pero luego envolví mi consulta SQL en otra instrucción SELECT y funciona!

Ej:

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

extraño ....

+0

Esto funcionó para mí. – AS7K

0

Tuve el mismo problema ... no usé dataReader.Read() en absoluto ... tomará el puntero a la siguiente fila. En su lugar, use directamente datatable.load (dataReader).

0

Sé que esto es una cuestión de edad, pero para mí el pensar que funcionó mientras la consulta de una base de datos de acceso y darse cuenta de que faltaba 1 fila de la consulta, iba a cambiar lo siguiente: -

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

    if(dataset.hasrows) - Missing row appears.