Ci è capitato diverse volte di dover esportare dei dati in da tabelle o viste di Sql Server o magari da griglie di pagine web di nostre applicazioni il cui datasource è creato "ad hoc" per la pagina. 

Presentiamo qui una semplice implementazione di un export in csv che fa uso dei Generics e della reflection.
public static void FromEnumerable<T>(IEnumerable<T> lista)
{
    if (lista == null || lista.Count() == 0)
        throw new ArgumentException("lista");

    StringBuilder sb = new StringBuilder();

    var properties = typeof(T).GetProperties();

    foreach (var item in lista)
    {
        List<string> valori = new List<string>();
        foreach (var property in properties)
        {
            string valore = Convert.ToString(property.GetValue(item, null) ?? "");
            valori.Add(valore);
        }
        sb.AppendLine(string.Join(";", valori));
    }

    using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"test.csv", true))
    {
        file.Write(sb.ToString());
    }
}
L'utilizzo dei generics nel metodo è fondamentale per poter utilizzare la reflection, ovviamente se passassimo una lista di oggetti non avremmo proprietà da estrarre.

 

Come prima cosa validiamo i dati in ingresso, ovviamente vogliamo una lista che non sia null o vuota. Fatto questo utilizziamo l'operatore "typeof" per avere il tipo "T" e poi estrarre le proprietà della nostra classe. In due cicli annidati estraiamo da ogni elemento della lista tutti i valori delle proprietà. e poi li scriviamo in un file di testo.
 
Per non dover gestire manualmente il separatore delle colonne utilizziamo il metodo string.join che fa il lavoro sporco per noi.
 
L'utilità di questo metodo risiede nello sfruttare la type inference del compilatore e utilizzare quindi classi anonime nel momento dell'export come dimostrato nell'esempio seguente.
var vec = new[] { new { Nome = "Max", Cognome = "Power" }, new { Nome = "Buzz", Cognome = "Lightyear" } };

ExportCsv.FromEnumerable(vec);

 

Nella prima riga istanziamo un vettore di oggetti anonimi (dello stesso tipo ovviamente), il compilatore lavora per noi generando la classe e quindi possiamo passare il tutto al nostro metodo. La praticità di questo metodo per noi risiede nel poter effettuare query ad hoc e esportarle "al volo".
comments powered by Disqus