giovedì 28 luglio 2011

How To: DataTable To List SOLVED.

Ammetto che come sfida non sia stata della più semplici, e credo che ormai il visitatore che ieri mi ha formulato la richiesta o abbia disistito, o ci sia riuscito..

cmq il nocciolo della questione era ottenere una List T partendo da una DataTable.

A tutti gli effetti DataTable presenta una metodo di cast, ma non è di certo
quello che fa.. anzi il cast accetta solo DataRow, che di aiuto non ne offre tanto.

Quindi mi sono deciso a provare con un delegato mio che operi in tal senso, basandomi
però sul concetto di Select tuttavia mi è servito comunque avere a disposizione il
cast.

public class entity
{
public int ID { get; set; }
public string Name{ get; set; }
public string Description { get; set; }

public override string ToString()
{
return string.Format("id>{0}|name>{1}|description>{2}",
ID, Name, Description);
}
}

public class entityList : List<entity>
{

}

class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable("myEntity");
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Description", typeof(string));

dt.Rows.Add(new object[] { 1, "Test_1", "Test_1" });
dt.Rows.Add(new object[] { 2, "Test_2", "Test_2" });
dt.Rows.Add(new object[] { 3, "Test_3", "Test_3" });


entityList el = new entityList();
for (int i = 0; i < dt.Rows.Count; i++)
{
Console.WriteLine(
"Id:{0} Name:{1} Description:{2}",
dt.Rows[i][0].ToString(),
dt.Rows[i][1].ToString(),
dt.Rows[i][2].ToString()
);

}

var output = dt.Rows.Cast<DataRow>().Select(r=>RealCast(r));

el.AddRange(output.ToArray());


for (int i = 0; i < el.Count; i++)
{
Console.WriteLine(
"Id:{0} Name:{1} Description:{2}",
el[i].ID.ToString(),
el[i].Name.ToString(),
el[i].Description.ToString()
);
}

Console.ReadLine();

}

private static entity RealCast(DataRow dr)
{
return new entity {

ID=Convert.ToInt32(dr[0]),
Name=dr[1].ToString(),
Description=dr[2].ToString()
};
}

}




Quindi i perfetto stile ecco che con un delegato

private static entity RealCast(DataRow dr)
{
return new entity {

ID=Convert.ToInt32(dr[0]),
Name=dr[1].ToString(),
Description=dr[2].ToString()
};
}


e una riga

var output = dt.Rows.Cast<DataRow>().Select(r=>RealCast(r));

el.AddRange(output.ToArray());


riusciamo a convertire
una DataTable in un entity (nota).. il divertente sarà risucire a farlo con generic... e chi mi ferma più !!!

Se volete fare qualche prova di giusto per comprendere quanto rende questo codice

static void Main(string[] args)
{
DataTable dt = new DataTable("myEntity");
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Description", typeof(string));

Console.WriteLine ("fill\r\n" +DateTime.Now.ToLongTimeString() +"." +
DateTime.Now.Millisecond.ToString().PadLeft(3,'0'));

for (int i = 0; i < 1000000; i++)
dt.Rows.Add(new object[] { i,
"Test" +i.ToString(),
"Test" +i.ToString() });


Console.WriteLine (DateTime.Now.ToLongTimeString() +"." +
DateTime.Now.Millisecond.ToString().PadLeft(3,'0'));

entityList el = new entityList();

Console.WriteLine ("conver\r\n" +DateTime.Now.ToLongTimeString() +"." +
DateTime.Now.Millisecond.ToString().PadLeft(3,'0'));

var output = dt.Rows.Cast<DataRow>().Select(r=>RealCast(r));

el.AddRange(output.ToArray());

Console.WriteLine (DateTime.Now.ToLongTimeString() +"." +
DateTime.Now.Millisecond.ToString().PadLeft(3,'0'));

Console.ReadLine();

}


0,7 secondi nel mio caso ... e sono rimasto abbastanza colpito!

Nessun commento: