Qualche giorno fa ho inserito un post sul forum perchè avevo bisogno di ottenere un DataSet, oppure un DataTable o un DataView, da un IDataReader.
Non avendo ottenuto risposta ho cercato un pò ed ho trovato diverse soluzioni, di cui una abbastanza elegante.
Il namespace System.Data.Common contiene una classe di nome DBDataAdapter, dalla quale ereditano tutti gli altri DataAdapter, che contiene un overload del metodo Fill (protected) che accetta come parametri un DataTable e un IDataReader, proprio ciò di cui avevo bisogno.
Quello che ho fatto è stato quindi creare un classe che derivasse da DBDataAdapter e che esponesse tale funzionalità con un metodo pubblico:
public class DataReaderAdapter : DbDataAdapter
{
public int FillFromReader(DataTable dataTable, IDataReader dataReader)
{
return this.Fill(dataTable, dataReader);
}
}
C'è la necessità tuttavia di implementare quattro metodi astratti di DBDataAdapter, quindi al codice della classe va aggiunto il seguente, ed il corpo dei quattro metodi può essere lasciato vuoto o riempito con il throw di un'eccezione come ha fatto per me ReSharper:
protected override RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
{
throw new NotImplementedException();
}
protected override RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
{
throw new NotImplementedException();
}
protected override void OnRowUpdated(RowUpdatedEventArgs value)
{
throw new NotImplementedException();
}
protected override void OnRowUpdating(RowUpdatingEventArgs value)
{
throw new NotImplementedException();
}
Il codice completo della classe risulta quindi:
public class DataReaderAdapter : DbDataAdapter
{
public int FillFromReader(DataTable dataTable, IDataReader dataReader)
{
return this.Fill(dataTable, dataReader);
}
protected override RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
{
throw new NotImplementedException();
}
protected override RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
{
throw new NotImplementedException();
}
protected override void OnRowUpdated(RowUpdatedEventArgs value)
{
throw new NotImplementedException();
}
protected override void OnRowUpdating(RowUpdatingEventArgs value)
{
throw new NotImplementedException();
}
}
Ora l'utilizzo della classe è molto semplice, per fare un esempio:
[...]
SqlDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
DataReaderAdapter da = new DataReaderAdapter();
da.FillFromReader(dt, dr);
[...]
Il link al post originale è questo: http://weblogs.asp.net/rosherove/archive/2004/01/22/61541.aspx, anche se la soluzione che ho adottato non è nel post ma in uno dei commenti.
Spero possa essere stato utile.
powered by IMHO 1.2