A generic database class

This is a class I use frequently for running SQL commands / queries:

public class Database : IDatabase
{
    public Database(DatabaseConfiguration config)
    {
        this.config = config;
    }
 
    public object[][] RunQuery(string queryparams object[] args)
    {
        using (var con = Connect())
        using (var cmd = Prepare(conqueryargs))
            return cmd.ExecuteReader().Pipe(ReadData);
    }
 
    public void RunNonQuery(string commandparams object[] args)
    {
        using (var con = Connect())
        using (var cmd = Prepare(concommandargs))
            cmd.ExecuteNonQuery();
    }
 
    //
 
    private static readonly ITableReader TABLE_READER = new TableReader();
 
    private readonly DatabaseConfiguration config;
 
    private SqlConnection Connect() =>
        new SqlConnection(config.ConnectionString).Apply(it => it.Open());
 
    private static object[][] ReadData(IDataReader reader=>
        TABLE_READER.ReadData(reader);
 
    private static SqlCommand Prepare(SqlConnection connectionstring sqlparams object[] args=>
        new SqlCommand(sqlconnection).Apply(it => AddParams(itargs));
 
    private static void AddParams(SqlCommand cmdIEnumerable<objectargs=>
        ToParams(args).Apply(cmd.Parameters.AddRange);
 
    private static SqlParameter[] ToParams(IEnumerable<objectargs=>
        args.Select(CreateParameter).ToArray();
 
    private static SqlParameter CreateParameter(object valueint index=>
        new SqlParameter($"@p{index + 1}"value);
}
This is using two helper classes: the TableReader class
internal class TableReader : ITableReader
{
    public object[][] ReadData(IDataReader reader)
    {
        var list = new List<object[]>();
 
        while (reader.Read())
        {
            var values = new object[reader.FieldCount];
            reader.GetValues(values);
            list.Add(values);
        }
 
        return list.ToArray();
    }
}
and the DatabaseConfiguration class
public class DatabaseConfiguration
{
    public string ConnectionString { getset; }
}
and also a couple of extension methods:
public static B Pipe<AB>(this A aFunc<ABfunc=> func(a);
 
public static A Apply<A>(this A aAction<Aaction)
{
    action(a);
    return a;
}
I am quite happy with the way this code looks - small classes and methods, everything should be pretty self-explanatory.

Comments

Popular posts from this blog

Posting dynamic Master / Detail forms with Knockout

Comparing Excel files, take two

EF Code First: seeding with foreign keys