using System; using System.Data; namespace CoPackLibrary.DataAccessLayer { public interface IQuery { void Prepare(IDbCommand command); } public interface IModifyQuery : IQuery { IQuery GetHistoryInsertUsing(DateTime updateDate); } public interface IResultQuery : IQuery { ReturnType MapResult(IDataReader reader); } /******************************************************/ /******************************************************/ public static class Query { public static IQuery For(string sql) { return For(cmd => cmd.CommandText = sql); } public static IQuery For(Action prepare) { return new DynamicQuery(prepare); } /******************************************************/ /******************************************************/ public static IResultQuery For(string sql) { return For(cmd => cmd.CommandText = sql); } public static IResultQuery For(IQuery query) { return For(query.Prepare); } public static IResultQuery For(Action prepareMethod) { return new ScalarQuery(prepareMethod); } /******************************************************/ /******************************************************/ public static IResultQuery For(string sql, Func mappingMethod) { return For(cmd => cmd.CommandText = sql, mappingMethod); } public static IResultQuery For(Action prepareMethod, Func mappingMethod) { return new ResultQuery(prepareMethod, mappingMethod); } /******************************************************/ /******************************************************/ private class DynamicQuery : IQuery { public DynamicQuery(Action prepareMethod) { _prepareMethod = prepareMethod; } private readonly Action _prepareMethod; public void Prepare(IDbCommand command) { _prepareMethod(command); } } private class ScalarQuery : IResultQuery { public ScalarQuery(Action prepareMethod) { _prepareMethod = prepareMethod; } private readonly Action _prepareMethod; public void Prepare(IDbCommand command) { _prepareMethod(command); } public T MapResult(IDataReader reader) { return !reader.Read() ? default(T) : (T)Convert.ChangeType(reader[0], typeof(T)); } } private class ResultQuery : IResultQuery { public ResultQuery(Action prepareMethod, Func mappingMethod) { _prepareMethod = prepareMethod; _mappingMethod = mappingMethod; } private readonly Action _prepareMethod; private readonly Func _mappingMethod; public void Prepare(IDbCommand command) { _prepareMethod(command); } public T MapResult(IDataReader reader) { return _mappingMethod(reader); } } } }