Consider the FetchData
method below. It is designed to avoid duplicating the database query code every time you want to fetch some data from the database.
List<MyData> myData = new List<MyData();
FetchData((IDataReader reader) =>
{
myData.Add(new MyData(reader.GetString(0), reader.GetInt32(1)));
}, "usp_get_my_data");
It works, but it would be nice if this object creation could somehow live inside the FetchData
method.
Is there a better approach?
Perhaps FetchData
can be modified to return a list of some type X directly?
protected void FetchData(Action<IDataReader> processor, String query)
{
using (var connection = CreateConnection())
{
connection.ConnectionString = ConnectionString;
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = query;
using (IDataReader reader = command.ExecuteReader())
{
while (reader.read())
{
processor(reader);
}
}
}
}
}
Using generics maybe?
protected IEnumerable<T> FetchData<T>(Func<IDataReader, T> processor, String query)
{
using (var connection = CreateConnection())
{
connection.ConnectionString = ConnectionString;
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = query;
using (IDataReader reader = command.ExecuteReader())
{
while (reader.read())
{
yield return processor(reader);
}
}
}
}
}
Then you can use the enumeration however you want:
var myData = FetchData<MyData>(reader => new MyData(reader.GetString(0), reader.GetInt32(1)), "usp_get_my_data").ToList();