using System.Collections.Generic;
using System.Data.SqlClient;
public bool IsSuccessful { get; set; }
public class RetrieveResult<T> : QueryResult
public T Value { get; set; }
public abstract class BaseDataAccess
private static string ConnectionString { get { return "ConnectionString"; } }
private T WithCommand<T>( string text, IEnumerable<SqlParameter> parameters, Func<SqlCommand,T> operation )
using( var cn = new SqlConnection( ConnectionString ) )
using( var cmd = new SqlCommand( text, cn ) )
if( parameters != null && parameters.Any() )
cmd.Parameters.AddRange( parameters.ToArray() );
private void WithCommand( string text, IEnumerable<SqlParameter> parameters, Action<SqlCommand> operation )
using( var cn = new SqlConnection( ConnectionString ) )
using( var cmd = new SqlCommand( text, cn ) )
if( parameters != null && parameters.Any() )
cmd.Parameters.AddRange( parameters.ToArray() );
private IList<DataRow> GetRows( SqlCommand cmd )
using( var dr = cmd.ExecuteReader() )
using( var da = new SqlDataAdapter() )
if( !dr.HasRows ) return new List<DataRow>();
var dt = new DataTable();
return dt.Rows.Cast<DataRow>().ToList();
protected RetrieveResult<IList<T>> GetCollection<T>( string query, IEnumerable<SqlParameter> parameters, Func<DataRow, T> builder )
var result = new RetrieveResult<IList<T>>() { IsSuccessful = false };
var rows = WithCommand( query, parameters, cmd => GetRows( cmd ) );
result.Value = rows.Select( row => builder( row ) ).ToList();
result.IsSuccessful = true;
protected RetrieveResult<T> GetSingle<T>( string query, IEnumerable<SqlParameter> parameters, Func<DataRow, T> builder )
var result = new RetrieveResult<T>() { IsSuccessful = false };
var row = WithCommand( query, parameters, cmd => GetRows( cmd ) ).Single();
result.Value = builder( row );
result.IsSuccessful = true;
protected QueryResult ExecuteCommand( string query, IEnumerable<SqlParameter> parameters )
var result = new QueryResult { IsSuccessful = false };
WithCommand( query, parameters, cmd => {} );
result.IsSuccessful = true;
public string name { get; set; }
public double price { get; set; }
public string size { get; set; }
public class StockDataAccess : BaseDataAccess
public RetrieveResult<stockItem> GetStockRecord( int stockItemNumber )
var query = "SELECT name, size, price FROM dbo.products WHERE itemnumber = @itemNumber";
new SqlParameter("@itemNumber", SqlDbType.Int) { Value = stockItemNumber }
var result = GetSingle( query, parameters,
name = row[ "name" ] as string,
price = (double)row[ "price" ],
size = row[ "size" ] as string
public static void Main()
var stockDa = new StockDataAccess();
var stockItem = stockDa.GetStockRecord( 1 );
if( stockItem.IsSuccessful )