Domanda

Sto lavorando con una struttura oggetto esistente che utilizza valori speciali per rappresentare NULL per primitive int, DateTime, a lungo. I dati che contengono questi valori si aggiungono a un DataTable e visualizzati in controlli di terze parti come ad esempio XtraGrid.

Tutto è bene, tranne quando gli aggregati vengono applicati ai dati. In questo caso, ovviamente, i valori speciali vengono elaborati anziché i valori NULL.

Quindi penso che la soluzione migliore è quella di mappare i valori da / per DBNull quando mettere in DataRow. Ho pensato di sottoclassi DataTable e DataRow, ma le classi base non permetto preponderante delle funzioni di accesso.

Potrei aggiungere get / set funzioni in più per le sottoclassi, ma questo si basa sul ricordo di usarli. Potrei aggiungere funzioni di supporto statici invece di sottoclassi, ma questo ha lo stesso problema.

C'è una soluzione più elegante?

Aggiorna E 'la griglia stessa che sta facendo l'aggregazione, in quanto ha controlli flessibili per consentire all'utente di definire riassunti in fase di esecuzione. Quindi penso che l'unica vera soluzione è quella di mappare da / per DBNull in qualche modo, solo in cerca di un modo elegante di fare questo.

È stato utile?

Soluzione

È possibile creare un metodo di estensione per aiutare a riempire il DataTable e convertire i valori DBNull:

public static class DataExtensions
{
    public static DataRow AddRow(this DataRowCollection rowCollection, params object[] values)
    {
        object[] newValues = new object[values.Length];

        for(int i=0;i<values.Length;i++)
        {
            object value = values[i];
            if (value != null)
            {                    
                Type t = value.GetType();
                //check for min value only for value types...
                if (t.IsValueType)
                {
                    //maybe you can do some caching for that...
                    FieldInfo info = t.GetField("MinValue",
                        System.Reflection.BindingFlags.Static
                        | System.Reflection.BindingFlags.Public
                        );
                    if (info != null)
                    {
                        object o = info.GetValue(null);
                        if (value.Equals(o))  //very important == will return false
                        {
                            value = DBNull.Value;
                        }
                    }
                }
            }
            newValues[i] = value;               
        }

        return rowCollection.Add(newValues);
    }
}

E allora si sarà in grado di scrivere qualcosa di simile:

t.Rows.AddRow(a,b,c,d,e);

Altri suggerimenti

forse si può creare aggregati condizionali con IIF come (sciocco esempio):

        DataTable t= new DataTable();
        t.Columns.Add("id");
        t.Columns.Add("id2");
        t.Columns.Add("id3", typeof(int), "IIF(id="+int.MinValue.ToString()+",id2,id+id2)");
        for (int i = 0; i < 5; i++)
        {
            t.Rows.Add(new object[] { i, 2 * i });
        }

        t.Rows.Add(new object[] { int.MinValue, 2000});

Modifica:. Adatto al tuo commento sul post di altri

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top