Share Pastebin
Guest
Public paste!

jeffreyabecker

By: a guest | Jul 2nd, 2009 | Syntax: C# | Size: 9.77 KB | Hits: 2 | Expires: Never
This paste has a previous version, view the difference. Copy text to clipboard
  1. /*
  2. ** 02/06/2009
  3. **
  4. ** The author disclaims copyright to this source code.  In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. **    May you do good and not evil.
  8. **    May you find forgiveness for yourself and forgive others.
  9. **    May you share freely, never taking more than you give.
  10. **
  11. **
  12. */
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Data;
  18. using System.Data.SqlClient;
  19.  
  20. namespace JB.DbExample
  21. {
  22.     public class DbParameter
  23.     {
  24.         public string Name { get; set; }
  25.         public object Value { get; set; }
  26.     }
  27.  
  28.     public interface IDbManager : IDisposable
  29.     {
  30.         /// <summary>
  31.         /// Executes a procedure returning the results as a DataSet
  32.         /// </summary>
  33.         /// <param name="procName">The name of the stored procedure</param>
  34.         /// <param name="args">the argument name/value pairs for the procedure</param>
  35.         /// <returns>the resuts as a data set</returns>
  36.         DataSet Exec(string procName, params DbParameter[] args);
  37.  
  38.         /// <summary>
  39.         /// Executes some sql returning the results as a DataSet
  40.         /// </summary>
  41.         /// <param name="sql">the sql to be executed</param>
  42.         /// <param name="args">the argument name/value pairs for the sql</param>
  43.         /// <returns>the resuts as a data set</returns>
  44.         DataSet ExecDynamicSql(string sql, params DbParameter[] args);
  45.  
  46.         /// <summary>
  47.         /// Executes a stored procedure and returns a single result
  48.         /// </summary>
  49.         /// <typeparam name="T">The type of the result</typeparam>
  50.         /// <param name="procName">the name of hte procedure</param>
  51.         /// <param name="args">the argument name/value pairs for the procedure</param>
  52.         /// <returns></returns>
  53.         T Scalar<T>(string procName, params DbParameter[] args);
  54.  
  55.         /// <summary>
  56.         /// Executes some sql returning a single result
  57.         /// </summary>
  58.         /// <typeparam name="T">The type of the result</typeparam>
  59.         /// <param name="sql">the sql to be executed</param>
  60.         /// <param name="args">the argument name/value pairs for the sql</param>
  61.         /// <returns></returns>
  62.         T ScalarDynamicSql<T>(string sql, params DbParameter[] args);
  63.  
  64.         /// <summary>
  65.         /// Begins a transaction.
  66.         /// </summary>
  67.         void Begin();
  68.  
  69.         /// <summary>
  70.         /// Commits a transaction.
  71.         /// </summary>
  72.         void Commit();
  73.         /// <summary>
  74.         /// Rolls a transaction back.
  75.         /// </summary>
  76.         void Rollback();
  77.     }
  78.     /// <summary>
  79.     /// Provides an "anonymous object as dictionary" interface to IDbManager
  80.     /// </summary>
  81.     public static class DbManagerExtensions
  82.     {
  83.         // This class contains Extension Methods which are a new feature in C# 3f
  84.  
  85.         //this method uses reflection to extract an object into name-value pairsf
  86.         private static DbParameter[] GetArgsFromObject(object obj)
  87.         {
  88.             List<DbParameter> parameters = new List<DbParameter>();
  89.             foreach (var propertyInfo in obj.GetType().GetProperties())
  90.             {
  91.                 parameters.Add(new DbParameter() { Name = propertyInfo.Name, Value = propertyInfo.GetValue(obj, null) });
  92.             }
  93.             return parameters.ToArray();
  94.         }
  95.  
  96.         /// <summary>
  97.         /// Executes a procedure returning the results as a DataSet
  98.         /// </summary>
  99.         /// <param name="db">the DbManager</param>
  100.         /// <param name="procName">The name of the stored procedure</param>
  101.         /// <param name="argsDict">the argument name/value pairs for the procedure</param>
  102.         /// <returns>the resuts as a data set</returns>
  103.         public static DataSet Exec(this IDbManager db, string procName, object argsDict)
  104.         {
  105.             return db.Exec(procName, GetArgsFromObject(argsDict));
  106.         }
  107.  
  108.         /// <summary>
  109.         /// Executes some sql returning the results as a DataSet
  110.         /// </summary>
  111.         /// <param name="db">the DbManager</param>
  112.         /// <param name="sql">the sql to be executed</param>
  113.         /// <param name="argsDict">the argument name/value pairs for the sql</param>
  114.         /// <returns>the resuts as a data set</returns>
  115.         public static DataSet ExecDynamicSql(this IDbManager db, string sql, object argsDict)
  116.         {
  117.             return db.ExecDynamicSql(sql, GetArgsFromObject(argsDict));
  118.         }
  119.         /// <summary>
  120.         /// Executes a stored procedure and returns a single result
  121.         /// </summary>
  122.         /// <param name="db">the DbManager</param>
  123.         /// <typeparam name="T">The type of the result</typeparam>
  124.         /// <param name="procName">the name of hte procedure</param>
  125.         /// <param name="argsDict">the argument name/value pairs for the procedure</param>
  126.         /// <returns></returns>
  127.         public static T Scalar<T>(this IDbManager db, string procName, object argsDict)
  128.         {
  129.             return db.Scalar<T>(procName, GetArgsFromObject(argsDict));
  130.         }
  131.         /// <summary>
  132.         /// Executes some sql returning a single result
  133.         /// </summary>
  134.         /// <param name="db">the DbManager</param>
  135.         /// <typeparam name="T">The type of the result</typeparam>
  136.         /// <param name="sql">the sql to be executed</param>
  137.         /// <param name="argsDict">the argument name/value pairs for the sql</param>
  138.         /// <returns></returns>
  139.         public static T ScalarDynamicSql<T>(this IDbManager db, string sql, object argsDict)
  140.         {
  141.             return db.ScalarDynamicSql<T>(sql, GetArgsFromObject(argsDict));
  142.         }
  143.     }
  144.  
  145.     public class DbManagerFactory
  146.     {
  147.         public static IDbManager GetDbManager(string connectionStringName)
  148.         {
  149.             return new SqlDbManager(System.Configuration.ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString);
  150.         }
  151.        
  152.         // this is the actual implementation of IDbManager.  It should never be instantiated outside the factory class
  153.         private class SqlDbManager : IDbManager
  154.         {
  155.             string _connectionString;
  156.             SqlConnection _conn;
  157.             SqlTransaction _trans;
  158.  
  159.             public SqlDbManager(string connectionString)
  160.             {
  161.                 _connectionString = connectionString;
  162.             }
  163.  
  164.             private SqlConnection GetConnection()
  165.             {
  166.                 if (_conn == null)
  167.                 {
  168.                     _conn = new SqlConnection(_connectionString);
  169.                     _conn.Open();
  170.                 }
  171.                 return _conn;
  172.             }
  173.  
  174.             #region IDbManager Members
  175.  
  176.             public DataSet Exec(string procName, params DbParameter[] args)
  177.             {
  178.                 SqlCommand cmd = new SqlCommand(procName, GetConnection());
  179.                 cmd.CommandType = CommandType.StoredProcedure;
  180.                 foreach (DbParameter p in args)
  181.                 {
  182.                     cmd.Parameters.AddWithValue(p.Name, p.Value);
  183.                 }
  184.                 DataSet ds = new DataSet();
  185.                 SqlDataAdapter adp = new SqlDataAdapter(cmd);
  186.                 adp.Fill(ds);
  187.                 return ds;
  188.             }
  189.  
  190.             public DataSet ExecDynamicSql(string sql, params DbParameter[] args)
  191.             {
  192.                 SqlCommand cmd = new SqlCommand(sql, GetConnection());
  193.                 cmd.CommandType = CommandType.Text;
  194.                 foreach (DbParameter p in args)
  195.                 {
  196.                     cmd.Parameters.AddWithValue(p.Name, p.Value);
  197.                 }
  198.                 DataSet ds = new DataSet();
  199.                 SqlDataAdapter adp = new SqlDataAdapter(cmd);
  200.                 adp.Fill(ds);
  201.                 return ds;
  202.             }
  203.  
  204.             public T Scalar<T>(string procName, params DbParameter[] args)
  205.             {
  206.                 DataSet ds = Exec(procName, args);
  207.                 return ds.Tables[0].Rows[0].Field<T>(0);
  208.             }
  209.  
  210.             public T ScalarDynamicSql<T>(string sql, params DbParameter[] args)
  211.             {
  212.                 DataSet ds = ExecDynamicSql(sql, args);
  213.                 return ds.Tables[0].Rows[0].Field<T>(0);
  214.             }
  215.  
  216.  
  217.  
  218.             public void Begin()
  219.             {
  220.                 if (_trans != null)
  221.                 {
  222.                     throw new DataException("Attempted to begin a transaction with one already pending.");
  223.                 }
  224.                 SqlConnection conn = GetConnection();
  225.                 _trans = conn.BeginTransaction();
  226.             }
  227.  
  228.             public void Commit()
  229.             {
  230.                 if (_trans == null)
  231.                     throw new DataException("Attempted to commit without a pending transaction.");
  232.                 _trans.Commit();
  233.                 _trans.Dispose();
  234.                 _trans = null;
  235.             }
  236.  
  237.             public void Rollback()
  238.             {
  239.                 if (_trans == null)
  240.                     throw new DataException("Attempted to roll back without a pending transaction.");
  241.                 _trans.Rollback();
  242.                 _trans.Dispose();
  243.                 _trans = null;
  244.             }
  245.             #endregion
  246.  
  247.             #region IDisposable Members
  248.  
  249.             public void Dispose()
  250.             {
  251.                 if (_trans != null)
  252.                 {
  253.                     _trans.Rollback();
  254.                     _trans.Dispose();
  255.                     throw new DataException("Disposed a connection with a pending transaction.  Make sure to explicitly commit or rollback your transactions");
  256.                 }
  257.                 if (_conn != null)
  258.                 {
  259.                     _conn.Dispose();
  260.                 }
  261.  
  262.             }
  263.  
  264.             #endregion
  265.  
  266.         }
  267.     }
  268. }