he hecho un poco a mí mismo con la evaluación comparativa de diversos enfoques:
public DataTable Read1(string query)
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = query;
cmd.Connection.Open();
var table = new DataTable();
using (var r = cmd.ExecuteReader())
table.Load(r);
return table;
}
}
public DataTable Read2<S>(string query) where S : IDbDataAdapter, IDisposable, new()
{
using (var da = new S())
{
using (da.SelectCommand = conn.CreateCommand())
{
da.SelectCommand.CommandText = query;
DataSet ds = new DataSet();
da.Fill(ds);
return ds.Tables[0];
}
}
}
public IEnumerable<S> Read3<S>(string query, Func<IDataRecord, S> selector)
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = query;
cmd.Connection.Open();
using (var r = cmd.ExecuteReader())
while (r.Read())
yield return selector(r);
}
}
public S[] Read4<S>(string query, Func<IDataRecord, S> selector)
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = query;
cmd.Connection.Open();
using (var r = cmd.ExecuteReader())
return ((DbDataReader)r).Cast<IDataRecord>().Select(selector).ToArray();
}
}
public List<S> Read5<S>(string query, Func<IDataRecord, S> selector)
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = query;
cmd.Connection.Open();
using (var r = cmd.ExecuteReader())
{
var items = new List<S>();
while (r.Read())
items.Add(selector(r));
return items;
}
}
}
1 y 2 vuelve DataTable
mientras que el resto inflexible de tipos conjunto de resultados, por lo que su exactitud no manzanas con manzanas, pero mientras el tiempo en consecuencia.
sólo lo esencial:
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 100; i++)
{
Read1(query); // ~8900 - 9200ms
Read1(query).Rows.Cast<DataRow>().Select(selector).ToArray(); // ~9000 - 9400ms
Read2<MySqlDataAdapter>(query); // ~1750 - 2000ms
Read2<MySqlDataAdapter>(query).Rows.Cast<DataRow>().Select(selector).ToArray(); // ~1850 - 2000ms
Read3(query, selector).ToArray(); // ~1550 - 1750ms
Read4(query, selector); // ~1550 - 1700ms
Read5(query, selector); // ~1550 - 1650ms
}
sw.Stop();
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
La consulta regresaron alrededor de 1200 filas y 5 campos (duración de 100 veces). Además de Read1
, todos funcionaron bien. De todos prefiero Read3
que devuelve datos de forma perezosa, como se enumera. Esto es ideal para la memoria si solo necesita enumerarla. Para tener una copia de la colección en la memoria, está mejor con Read4
o Read5
a su gusto.
Esto no es más rápido que el código que publiqué en la pregunta original (es más o menos el mismo), pero creo que es la más rápida de las respuestas. Al menos ahora sabemos que no hay un método más rápido que me faltaba. –