Consulta de C # y SQL Server devolviendo columnas nulas en una tabla grande

.net .net-core c# dapper sql-server

Pregunta

Estoy ejecutando la siguiente consulta en una tabla que tiene alrededor de 600 columnas:

SELECT * 
FROM Table 
WHERE [Owner] = 1234

Estoy ejecutando esta consulta usando EF code-first y Dapper y estoy logrando el mismo problema con ambos.

En particular, muchas filas que tienen un valor se devuelven como DBNull de la consulta (I verificó utilizando SQL Server Management Studio que las columnas tienen datos). Curiosamente, solo ocurre cuando se solicitan todas las columnas (ya sea usando * o tirando de ellas explícitamente).

Por ejemplo, si el Status columna tiene el valor "A" , la consulta devuelve DBNull como su valor. Pero si en lugar del código anterior (que tira de las 600 columnas) utilizo esta consulta:

SELECT [Status] 
FROM Table 
WHERE [Owner] = 1234

La columna Status está correctamente poblada.

Aquí está el código Dapper que estoy usando para procesar los resultados:

public IList<Dictionary<string, string>> GetData() {
    var sql = "SELECT * FROM Table WHERE [Owner] = 1234";
    var cn = new SqlConnection(serverConnectionString);
    var rows = new List<Dictionary<string, string>>();

    using (var reader = cn.ExecuteReader(sql))
    {
        while (reader.Read())
        {
            var dict = new Dictionary<string, string>();

            for (var i = 0; i < reader.FieldCount; i++)
            {
                var propName = reader.GetName(i).ToLowerInvariant();

                // This is set to DBNull for most, but not all,
                // columns if querying the ~600 columns in the Table
                var propValue = reader.GetValue(i); 

                dict[propName] = propValue?.ToString();
            }

            rows.Add(dict);
        }
    }

    return rows;
}

No puedo hacer cabeza o cola de este comportamiento. Cualquier ayuda sería muy apreciada.

Respuesta popular

Pruebe la extensión .Query () de Dapper para devolver una lista de objetos dinámicos. A continuación hay una prueba rápida:

[Test]
public void Test_Large_Number_of_Columns()
{
    const int n = 600;
    var cols = "";

    for (var i = 0; i < n; i++)
    {
        cols += "col" + i + " varchar(50) null,";
    }

    var create = String.Format("IF OBJECT_ID('dbo.foo', 'U') IS NOT NULL DROP TABLE dbo.foo; create table foo({0})", cols);

    using (var conn = new SqlConnection(@"Data Source=.\sqlexpress;Integrated Security=true; Initial Catalog=foo"))
    {
        conn.Execute(create);

        conn.Execute("insert into foo(col300) values('hello') ");

        var result = conn.Query("select * from foo").AsList();

        Assert.That(result[0].col300, Is.EqualTo("hello"));

    }
} 


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué