<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      【C#|.NET】從細節出發(二) 善用泛型 委托

      2013-03-26 18:32  熬夜的蟲子  閱讀(2337)  評論(1)    收藏  舉報

      系列文章完成后 源碼發布在我的GIT上 https://github.com/dubing/

      文章僅代表個人觀點  旨在交流 歡迎討論


       

      正文

        按照上一篇結尾留下的話題,本篇著重對數據庫操作方面也就是常用工廠模式的地方來進行泛型 委托方向的使用。

        一般大型項目中大家都喜歡依賴注入的方式來數據庫操作進行設計,也就是站在面向組件的層次。這里不討論這樣設計的優缺點,我們來看下如果不適用這種方式,只使用委托和泛型如何來良好的替代上面的方案。

        首先分析下sql操作有哪些元素。

          public class BaseDriverParam
          {
              public DbCommand baseCommand { get; set; }
              public DbConnection baseConnection { get; set; }
              public DataAdapter baseDataAdapter { get; set; }
              public DataParameter baseDataParameter { get; set; }
              public DbTransaction baseDbTransaction { get; set; }
              public DbDataReader baseDbDataReader { get; set; }
          }
      

        這里只是一部分,當然也是最常用的部分。選擇抽出這些是因為大部分數據庫的驅動都支持這些。舉個數據庫連接的例子

      public sealed class OleDbConnection : DbConnection, ICloneable, IDbConnection, IDisposable
      public sealed class MySqlConnection : DbConnection, ICloneable
      public sealed class SqlConnection : DbConnection, ICloneable
      public sealed class SQLiteConnection : DbConnection, ICloneable
      public sealed class OracleConnection : DbConnection, ICloneable
      

        一些特殊的內容例如 DataParameter在 IDbDataParameter中并不滿足需求的場合下我們選擇自己填充,同樣的還有下面所有的SqlCommandData等,因為不是文章主旨想表達的內容就不啰嗦了。

          明白這些,下面我們就開始一步一步設計,數據庫的常用操作有哪些doCreateConnection創建鏈接,doCreateCommand聲明操作命令,doCreateDataAdapter創建數據適配器,doFillCommand執行命令等等...

        這里我們做第一個選擇,按照工廠模式,這些內容都是分別在各自的類中實現,那么既然我們已經擯棄了這種方案,那么我們該如何設計比較合理,用泛型么,將不同的驅動參數作為可變元素帶入統一的方法中,聽起來是不錯的,我們先來建立方法結構

       public class TBaseDriver<TCommand, TDbConnection, TDataAdapter, TDataParameter, TDbTransaction> : BaseDriver
              where TCommand : DbCommand, new()
              where TDbConnection : DbConnection, new()
              where TDataAdapter : DbDataAdapter, new()
              where TDbTransaction : DbTransaction, new()
              where TDataParameter : DataParameter,new()
      

        然后我們逐一的實現方法,在這過程中我們會發現并不是所有的方法都符合我們的需求,例如DbDataAdapter中,標準的command要分很多種類型,例如增刪查改。然后對于DbDataAdapter沒有一個標準的構造函數例如public SqlDataAdapter(SqlCommand selectCommand)這種形式。這樣對于不同的類型又要分開操作。既然我們要選擇最簡潔的方法,自然這樣的方式我們就先不考慮了。那么我們把眼光再網上拋一層,以方法直接作為可變元素。

              public delegate string ActionDelegate();
              public delegate IConnectionEx CreateConnectionExDelegate();
              public delegate DbCommand CreateCommandDelegate(string dbClause);
              public delegate DbConnection CreateConnectionDelegate(string dbConnection);
              public delegate DbConnection CreateFrontConnectionDelegate(string dbConnection);
              public delegate DbCommand FillCommandDelegate(DbCommand dbCommand, SqlCommandData sqlCD);
              public delegate DataAdapter CreateDataAdapter(DbCommand dbCommand);
      

        然而我們并非籠統的講所有的方法都抽出,這樣也就是失去了文章本來想要表達的意思。這里我們是將原來基礎的方法分解,抽出可憐的邏輯設計成委托。舉2個簡單的例子

             public DbCommand CreateCommand(SqlCommandData sql)
                  {
                      DbCommand _c = doCreateCommand(sql.SqlClause);
      
                      myConnection.Open();
                      if (IsTransaction && myTransaction == null)
                      {
                          myTransaction = myConnection.BeginTransaction();
                      }
      
                      if (IsTransaction)
                      {
                          if (myTransaction == null)
                          {
                              myTransaction = myConnection.BeginTransaction();
                          }
                          _c.Transaction = myTransaction;
                      }
                      _c.Connection = myConnection;
                      _c.CommandTimeout = 300;
                      _c.CommandType = sql.CommandType;
      
                      _c = doFillCommand(_c, sql);
      
                      return _c;
                  }
      
                  public DataTable Query(SqlCommandData sql)
                  {
                      using (DbCommand _c = this.CreateCommand(sql))
                      {
                          DataAdapter _s = doCreateDataAdapter(_c);
                          DataSet _d = new DataSet();
                          _s.Fill(_d);
                          PopuloateCommand(_c, sql);
                          if (!Create)
                          {
                              Dispose(true);
                          }
                          return _d.Tables[0];
                      }
                  }
      

        那么我們在各自的驅動類中實現這里委托的邏輯,例如oracle的驅動中

      public class OracleDriver : BaseDriver
          {
              public OracleDriver()
              {
                  this.doCreateConnectionEx = () =>
                      {
                          MaoyaDbConnection mc = new MaoyaDbConnection();
                          mc.ConnectionString = this.ConnectionString;
                          mc.Create = true;
                          
                          mc.doCreateConnection = (conn) =>
                              {
                                  return new OracleConnection(conn);
                              };
                          mc.doCreateFrontConnection = (conn) =>
                              {
                                  return this.CreateConnection<OracleConnection>(conn);
                              };
                          mc.doCreateCommand = (comm) =>
                              {
                                  return new OracleCommand(comm);
                              };
                          mc.doCreateDataAdapter = (sqlcomm) =>
                              {
                                  return new OracleDataAdapter((OracleCommand)sqlcomm);
                              };
                          mc.doFillCommand = (sqlcomm, sql) =>
                              {
                                  foreach (DataParameter dp in sql.Parameters)
                                  {
                                      OracleParameter p = new OracleParameter();
                                   
                                      p.ParameterName = dp.ParameterName;
                                      p.Size = dp.Size;
                                      p.Direction = dp.Direction;
                                      p.IsNullable = dp.IsNullable;
                                      p.Value = dp.Value == null ? DBNull.Value : dp.Value;
      
                                      sqlcomm.Parameters.Add(p);
                                  }
                                  return sqlcomm;
                              };
                          return mc;
                      };
      
              }
          }
      

        或者在mysql的驅動中

          public class MySqlDriver : BaseDriver
          {
              public MySqlDriver()
              {
                  this.doCreateConnectionEx = () =>
                      {
                          MaoyaDbConnection mc = new MaoyaDbConnection();
                          mc.ConnectionString = this.ConnectionString;
                          mc.Create = true;
                          
                          mc.doCreateConnection = (conn) =>
                              {
                                  return new MySqlConnection(conn);
                              };
                          mc.doCreateFrontConnection = (conn) =>
                              {
                                  return this.CreateConnection<MySqlConnection>(conn);
                              };
                          mc.doCreateCommand = (comm) =>
                              {
                                  return new MySqlCommand(comm);
                              };
                          mc.doCreateDataAdapter = (sqlcomm) =>
                              {
                                  return new MySqlDataAdapter((MySqlCommand)sqlcomm);
                              };
                          mc.doFillCommand = (sqlcomm, sql) =>
                              {
                                  foreach (DataParameter dp in sql.Parameters)
                                  {
                                      MySqlParameter p = new MySqlParameter();
                                   
                                      p.ParameterName = dp.ParameterName;
                                      p.Size = dp.Size;
                                      p.Direction = dp.Direction;
                                      p.IsNullable = dp.IsNullable;
                                      p.Value = dp.Value == null ? DBNull.Value : dp.Value;
      
                                      sqlcomm.Parameters.Add(p);
                                  }
                                  return sqlcomm;
                              };
                          return mc;
                      };
      
              }
          }
      

        這么寫似乎是ok了,但是我們發現各個驅動中還是有很多可以抽出通用的部分,那么我們重回泛型的概念

          public class TBaseDriver<TCommand, TDbConnection, TDataAdapter, TDataParameter, TDbTransaction> : BaseDriver
              where TCommand : DbCommand, new()
              where TDbConnection : DbConnection, new()
              where TDataAdapter : DbDataAdapter, new()
              where TDbTransaction : DbTransaction, new()
              where TDataParameter : DataParameter,new()
          {
             
              public TBaseDriver()
              {
                  this.doCreateConnectionEx = () =>
                  {
                      MaoyaDbConnection mc = new MaoyaDbConnection();
                      mc.ConnectionString = this.ConnectionString;
                      mc.Create = true;
      
                      mc.doCreateConnection = (conn) =>
                      {
                          var baseConn = new TDbConnection();
                          baseConn.ConnectionString = conn;
                          return baseConn;
                      };
                      mc.doCreateFrontConnection = (conn) =>
                      {
                          return this.CreateConnection<TDbConnection>(conn);
                      };
                      mc.doCreateCommand = (comm) =>
                      {
                          var baseComm = new TCommand();
                          baseComm.CommandText = comm;
                          return baseComm;
                      };
                     
                      mc.doFillCommand = (sqlcomm, sql) =>
                      {
                          foreach (DataParameter dp in sql.Parameters)
                          {
                              TDataParameter p = new TDataParameter();
      
                              p.ParameterName = dp.ParameterName;
                              p.Size = dp.Size;
                              p.Direction = dp.Direction;
                              p.IsNullable = dp.IsNullable;
                              p.Value = dp.Value == null ? DBNull.Value : dp.Value;
      
                              sqlcomm.Parameters.Add(p);
                          }
                          return sqlcomm;
                      };
                      return mc;
                  };
      
              }
      
              
          }
      

        這里我們將可以共通的方法抽出,至于doCreateDataAdapter方法我們再各自的驅動類中實現即可。


      題外

        本篇到此結束,所示代碼僅供參考未經測試,功能也只是部分,例如事務操作都沒有闡述等等。下一篇和大家一起討論下依賴注入的一些另類實現方法。

       

      主站蜘蛛池模板: 蜜桃亚洲一区二区三区四| 国产va免费精品观看精品| 男人的天堂av一二三区| 国产伦一区二区三区精品| 在线视频观看| 亚洲av成人免费在线| 性色av无码久久一区二区三区| 国产精品福利在线观看无码卡一| 丰满少妇内射一区| 国产999久久高清免费观看| 欧美一本大道香蕉综合视频| 亚洲av二区三区在线| 久久影院午夜伦手机不四虎卡| 亚洲AVAV天堂AV在线网阿V| 亚洲天堂亚洲天堂亚洲色图| 无码精品人妻一区二区三区老牛| 欧美日产国产精品日产| 视频一区视频二区卡通动漫| 亚洲人成网站18禁止无码| 不卡一区二区国产在线| 中国女人大白屁股ass| 欧美乱大交aaaa片if| 午夜射精日本三级| 被黑人巨大一区二区三区| 国产永久免费高清在线观看 | 中国亚洲女人69内射少妇| 亚洲国产女性内射第一区| 日韩三级一区二区在线看| 欧美另类videossexo高潮| AV区无码字幕中文色| 老司机午夜精品视频资源| 九九热久久只有精品2| 影音先锋人妻啪啪av资源网站| 在线免费观看毛片av| 亚洲成人午夜排名成人午夜| 中文字幕人妻熟女人妻a片| 午夜成人理论无码电影在线播放 | 亚洲熟妇AV午夜无码不卡| 陆川县| 国产精品黄色精品黄色大片 | 国产suv精品一区二区五|