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

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

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

      最近花了二個月的業余時間重寫了我以前的通用數據訪問層, 由于是重寫,所以我給這個項目取了個新名字:ClownFish

      如果需要了解ClownFish的使用方法,請點擊ClownFish 使用說明

      ClownFish是什么?

      ClownFish 是我編寫的一個通用數據訪問層,設計它的目的是為了:
      1. 方便在 .net 項目中執行數據訪問任務。
      2. 避免直接使用ADO.NET帶來的一大堆高度類似的繁瑣代碼。
      3. 提供出色的性能滿足實際項目需要。

      ClownFish 具有以下一些技術特色:
      1. 高性能:比手寫代碼還快的執行速度。
      2. 簡單:執行查詢、將查詢結果轉成實體列表、獲取輸出參數。 一個調用完成三個步驟。
      3. 方便:提供專用的代碼生成器,直接生成調用代碼或者實體類型定義代碼。
      4. 通用:可以非常簡單地實現對多種數據庫的支持。
      5. 靈活:支持存儲過程,參數化SQL,或者將SQL語句保存在XML配置文件中。
      6. 可監控:提供一個Profiler工具,讓您可以隨時了解詳細的數據庫訪問情況。

      ClownFish不僅繼承了老版本的通用數據訪問層的全部優點, 而且在高性能,方便性,靈活性,以及代碼可讀性方面有了更出色的設計。

      在最新的版本中,ClownFish不僅僅只是一個通用數據訪問層, 還提供了:專用的代碼生成器,XmlCommand管理工具,Profiler工具,它們都會為ClownFish提供更多功能。

      ClownFish 是一個可免費的數據訪問組件,您可以把它應用在您的 .net 項目中,讓它簡化您的開發工作。

      比手寫代碼還快的執行速度

      提高性能是創建ClownFish項目的重要原因之一,這次優化的主要目標是:比手寫代碼還快的執行速度。

      為了讓您對ClownFish的性能留有較深刻的印象,下面我將通過一個實際案例來測試它的速度。

      首先,我定義了一個實體類型:

      定義這個實體類型,我關注的是它所包含的數據成員的數量,而不是那些數據成員的含義。
      我認為這個類型的數據成員數量應該還是比較接近多數實際場景的。
      下面再來看看如何從數據庫中加載它們:

      代碼中,首先定義了一個參數化的SQL查詢語句,然后就是純手工的ADO.NET代碼,循環調用SqlDataReader.Read()方法,再從SqlDataReader中根據字段名稱獲取數據寫入到實體對象的屬性中。

      這段代碼夠【手工化】吧? 由于這段代碼沒用使用反射代碼,所以如果想追求性能,我想大家都會這樣寫。

      在我的測試程序中,上面那段代碼被下面這段代碼調用:

      測試代碼應該沒有問題吧?


      再來看一下使用ClownFish的等效測試代碼:

      [TestMethod("ClownFish,SQLSERVER", 2)]
      public class Test_ClownFish_ShareConnection : IPerformanceTest
      {
          private UiParameters uiParam;
          private ClownFish.DbContext db;
      
          public Test_ClownFish_ShareConnection(UiParameters param)
          {
              this.uiParam = param;
              this.db = new ClownFish.DbContext(false);
          }
      
          public List<OrderInfo> Run()
          {
              var parameter = new { TopN = uiParam.PageSize };
              return ClownFish.DbHelper.FillList<OrderInfo>(
                          TestHelper.QueryText, parameter, db, ClownFish.CommandKind.SqlTextWithParams);
          }
      
          public void Dispose()
          {
              db.Dispose();
          }
      }
      

      比較這二段代碼,不難看出:使用 ClownFish 所需的代碼量要 少很多。

      如果我以下面的測試參數執行性能測試:

      可以得到下面的測試結果:

      圖形反映的結果很直觀:ClownFish 完成測試所需時間比手寫代碼要略快點。

      或許有些人認為:快這么一點,意義不大!
      但您想過沒有:ClownFish PK的對象是【手工版的專用代碼】?。?

      其實這個測試并沒有把 ClownFish 性能很好的體現出來,因為中間有SQLSERVER的執行時間,以及跨進程的調用開銷。 這二個因素所花的成本影響了ClownFish的性能優勢。

      下面,我又做了一組測試:直接從DataTable中加載數據。
      我之所以選擇這個測試方法,是因為它也是一種常見的使用方案:
      我們可以將原始導出到XML文件中,然后使用XML文件做離線數據,這樣可以減少對數據庫的訪問壓力。
      老版本的通用數據訪問層也一直支持這個功能,所以這次就選擇了這個測試方法。
      說明:實際使用時,我會從XML讀出數據到DataTable,供后面使用(轉成實體類型只是其中的一種使用數據的方式)。

      在測試之前,我們來看一下手工代碼是什么樣的:

      看到這個版本的LoadOrderInfo方法,您會有什么感覺?是不是很無奈?
      沒辦法,ADO.NET就是這樣設計的。寫這樣的代碼會讓人心煩(這是我的感受)!

      測試調用代碼:

      測試代碼應該沒有問題吧?


      再來看一下使用ClownFish的等效測試代碼:

      [TestMethod("ClownFish,DataTable", 6)]
      public class Test_ClownFish_LoadDataTable : IPerformanceTest
      {
          public Test_ClownFish_LoadDataTable(UiParameters param) { }
          public void Dispose() { }
      
          public List<OrderInfo> Run()
          {
              return ClownFish.DbHelper.FillListFromTable<OrderInfo>(TestHelper.GetOrderInfoTable());
          }        
      }
      

      使用 ClownFish 的代碼仍然要短很多!

      下面繼續使用前面的測試參數來運行測試程序,得到以下測試結果:

      Excel圖形直觀反映出 ClownFish 的速度要 比手工代碼 快一倍 還不止。

      看完這二個測試,ClownFish 有沒有給您留下二個印象?
      1. 代碼量很少。
      2. 性能很好。

      簡單,一個調用完成你要的全部功能

      調用下面這個存儲過程,您需要多少行C#代碼?

      create procedure InsertProduct( 
          @ProductName nvarchar(50), 
          @CategoryID int, 
          @Unit nvarchar(10), 
          @UnitPrice money, 
          @Quantity int, 
          @Remark nvarchar(max),
          @ProductID int output
      ) 
      as
      begin
      
      insert into Products (ProductName, CategoryID, Unit, UnitPrice, Quantity, Remark) 
      values( @ProductName, @CategoryID, @Unit, @UnitPrice, @Quantity, @Remark);
      
      set @ProductID = scope_identity();
      
      end
      

      在這里,我不想再想寫那種手工版本的ADO.NET代碼,我懶得寫。

      來看一下我從示例代碼中摘選出來的調用代碼吧:

      Product product = CreateTestProduct();
      
      // 插入一條新記錄
      DbHelper.ExecuteNonQuery("InsertProduct", product);
      sb.AppendFormat("InsertProduct OK, ProductId is : {0}\r\n", product.ProductID);
      

      看到了吧,其實只有一行代碼(中間那行)。

      再來看一個有分頁的吧:

      相應的調用代碼:

      // 查詢一個分頁列表
      var parameters = new GetProductByCategoryIdParameters {
          CategoryID = 1,
          PageIndex = 0,
          PageSize = 3,
          TotalRecords = 0
      };
      List<Product> list = DbHelper.FillList<Product>("GetProductByCategoryId", parameters);
      
      sb.AppendFormat("存在 {0} 條符合條件的記錄。條件:CategoryID = {1}\r\n", 
                              parameters.TotalRecords, parameters.CategoryID);
      

      還是 一個調用 就能完成全部的數據庫訪問工作。

      老版本的通用數據訪問層有這樣一個設計目標:
      調用存儲過程,不管輸入參數多么復雜,不管有多少輸出參數,包含轉換結果集到實體列表,只需要一行C#代碼。

      這一優點在ClownFish中得到了繼承:簡單,一個調用完成你要的全部功能。

      方便,你需要的代碼已經準備好了

      看到前面的那段演示代碼,你會不會想:我還要定義一個GetProductByCategoryIdParameters類型啊,太麻煩了!

      真是那樣嗎? 請看下面的截圖:

      注意:ClownFish并非僅僅支持存儲過程,后面將要介紹的XmlCommand也有同樣好的支持。

      在工具中,不僅可以直接查看存儲過程代碼,還能生成調用代碼。
      工具生成二個調用代碼,你可以選擇其中的一個(因為我不知道你需要哪個)。

      說明:調用GetProductByCategoryId需要定義一個類型是因為它包含了輸出參數,如果沒有輸出參數,工具會生成匿名類型:

      接下來的事情我想大家都知道該怎么做:把工具生成的代碼COPY到項目中,修改一下調用參數就好了。

      定義數據實體類型不再是費力的體力勞動

      對于喜歡使用數據實體類型的人來說,手工定義這些類型是件費力且枯燥的體力勞動。
      現在好了,ClownFish 的生成器可以減輕你的工作負擔:



      還記得本文一開始的那個OrderInfo類型嗎,它是根據一個查詢語句生成的:

      說明:根據查詢生成的類型,工具不知道如何命名,需要你在使用時改名。

      ClownFish 不僅僅能生成數據實體類型,還能生成對應的增刪改命令及其對應的命令參數:

      這里涉及到另一個名詞:XmlCommand。它是什么,我后面再說。
      這個截圖是想告訴你:以后不必再為增刪改命令以及那些命令參數煩惱了。
      執行圖片中那個菜單操作,然后再到ClownFish的另一個輔助工具(XmlCommandTool)去粘貼就可以了。

      通用,可以非常簡單地實現對多種數據庫的支持

      ClownFish已經從前輩版本中繼承了對多數據庫種類的支持。
      本文的結尾處,我提供了可供下載的完整示例,其中就包含有:SQLSERVER, MySql, ACCESS的示例代碼。 以下是其中一個示例的截圖:

      ClownFish 支持多種數據庫的原因在于:
      ClownFish 在內部使用了DbConnection, DbCommand, DbTransaction這些抽象類型。
      ClownFish 提供的API是不區分數據庫種類的,您在注冊連接時,指定什么類型,就是什么類型。

      因此,如果您使用存儲過程,或者XmlCommand的話,完全可以做到:一份C#代碼同時支持多種數據庫的。

      靈活,SQL語句放在哪里隨便你

      對于數據庫的訪問方式目前有以下5種方案:
      1. 有些人喜歡使用存儲過程。
      2. 有些人不喜歡存儲過程也不喜歡把SQL語句放在C#代碼中。
      3. 有些人會在C#中嵌入參數化的SQL語句。
      4. 有些人就是喜歡在C#代碼中拼接SQL語句。
      5. 還有些人不寫SQL語句而在使用ORM工具。
      當然了,還有些人同時混合使用多種方案。
      我不知道您屬于哪一類,如果是最后一類,那么我只能說:ClownFish不適合你。
      除此之外,ClownFish完全可以滿足您的需要。

      對于前4類方式,ClownFish在內部定義一個枚舉來表示:

      /// <summary>
      /// 表示要執行什么類型的命令
      /// </summary>
      public enum CommandKind
      {
          /// <summary>
          /// 表示要執行一個存儲過程或者是一個XmlCommand
          /// </summary>
          SpOrXml,
          /// <summary>
          /// 表示要執行一個存儲過程
          /// </summary>
          StoreProcedure,
          /// <summary>
          /// 表示要執行一個XmlCommand
          /// </summary>
          XmlCommand,
          /// <summary>
          /// 表示要執行一條沒有參數的SQL語句
          /// </summary>
          SqlTextNoParams,
          /// <summary>
          /// 表示要執行一條包含參數的SQL語句
          /// </summary>
          SqlTextWithParams
      }
      

      ClownFish提供了一個工具類:DbHelper,可以讓您方便地訪問數據庫, 它的許多數據庫訪問方法可以指定一個CommandKind枚舉表示要執行的命令類型:

      public static class DbHelper
      {
          public static int ExecuteNonQuery(
                  string nameOrSql, object inputParams);
          
          public static int ExecuteNonQuery(
                  string nameOrSql, object inputParams, CommandKind cmdKind);
          
          public static int ExecuteNonQuery(
                  string nameOrSql, object inputParams, DbContext dbContext);
          
          public static int ExecuteNonQuery(
                  string nameOrSql, object inputParams, DbContext dbContext, CommandKind cmdKind);
          
          // 其它的數據庫訪問方法就不一一列出了,可以查閱API文檔。
      }
      

      DbHelper的所有數據庫訪問方法都提供與以上類似的4個重載方法。
      那些方法中,第一個參數可以傳入一個SQL語句,或者一個存儲過程的名字,或者一個XmlCommand的名稱。
      參數 cmdKind 的意義就是解釋第一個參數的含義。

      XmlCommand是什么?

      前面已經多次提到了XmlCommand,這里來解釋一下XmlCommand是什么。

      上一小節中的那些數據訪問方法中,有一類較為特殊:不使用存儲過程,也不把SQL語句混在C#代碼中。
      對于這種方案,就需要把SQL語句放在配置文件中。

      或許有些人知道:我是喜歡用存儲過程的。我之所以喜歡存儲過程,是因為存儲過程的代碼與項目代碼是獨立的, 我可以單獨修改存儲過程。而且,我還喜歡參數化的查詢,反對使用拼接SQL語句。 我認為我是將數據庫做為我的SQL語句保存容器在使用,存儲過程只是這一種方式而已(因為它有參數管理功能)。

      除了存儲過程之外,使用配置文件也能完成同樣功能:1. SQL語句的保存容器,2. 提供參數管理功能。

      雖然ClownFish前輩版本也可以支持這種方案, 但是卻沒有定義一種配置文件的存放格式, 因此,需要自己設計配置文件格式,以及提供自己的簡化包裝方法。 對于這種方案來說,本身是沒有任何技術難度的,只是需要定義一種配置文件的存放格式。 現在,ClownFish已經正式提供這種支持,并提供了一個管理工具。

      我把保存在配置文件中的SQL語句稱為 XmlCommand ,一個XML文件中可以保存多個XmlCommand, 每個XmlCommand都有一個名稱以便在運行時區分。下面是一個XmlCommand的代碼片段:

          <XmlCommand Name="UpdateProduct">
              <Parameters>
                  <Parameter Name="@ProductName" Type="String" Size="50" />
                  <Parameter Name="@CategoryID" Type="Int32" />
                  <Parameter Name="@Unit" Type="String" Size="10" />
                  <Parameter Name="@UnitPrice" Type="Currency" />
                  <Parameter Name="@Quantity" Type="Int32" />
                  <Parameter Name="@Remark" Type="String" Size="-1" />
                  <Parameter Name="@ProductID" Type="Int32" />
              </Parameters>
              <CommandText><![CDATA[
      update Products 
      set ProductName = @ProductName, 
          CategoryID = @CategoryID, 
          Unit = @Unit, 
          UnitPrice = @UnitPrice, 
          Quantity = @Quantity, 
          Remark = @Remark 
      where ProductID = @ProductID;
      ]]></CommandText>
          </XmlCommand>
      

      看到這段代碼,您會不會想:維護它們是不是很麻煩?

      其實不是的,ClownFish提供了一個工具,可以輕松地管理它們:

      在這個對話框中,每個XmlCommand的屬性都提供了控件編輯功能,完全不需要手工維護那段XML文本。

      雙擊某個XmlCommand節點,還可以查看調用代碼:

      工具生成的調用代碼會告訴你那個XmlCommnad有多少個參數,您根本不用記住它們。

      還有一點:
      XmlCommand的XML文件可以是多個,可以按照不同的業務邏輯來組織它們,例如:

      對于一個ASP.NET項目來說,ClownFish 還會監視這個已加載的目錄,如果目錄中的配置文件有修改,會自動重新加載。

      可監控,圖形的工具會告訴你每個數據訪問的細節

      由于ClownFish是個數據訪問層,因此,它知道每次執行數據庫操作的所有信息。 所以,我提供了一個監控工具,用于查看解詳細的數據庫訪問情況。

      上圖反映了在執行MySql,Access的訪問情況。

      上圖反映了事務的執行情況,以及某個語句執行失敗的情況。

      根據工具窗口,我們可以直觀的查看到每個連接中執行了多少次命令, 它們是否屬于同一個事務,它們的類型是存儲過程,XmlCommand,SQL語句,全都一目了然。 而且,還可以知道每個命令的執行參數是什么:



      或許有些人看了這個工具后,會認為它是多余的,他總認為有個【SQL Server Profiler】,其它的東西都是沒有意義的。
      我不知道他有沒有想過: 用SQL Server Profiler去監視一個局域網的SQL Server實例,你還能分辨哪些操作是由你引發的嗎??

      我的工具則不同,它是配合我的數據訪問層一起工作的,由我的數據訪問層告訴工具當前用戶觸發了什么數據庫的操作。
      因此在分析本機程序訪問數據庫時,可以很直觀的知道:
      您的某個操作引發了什么樣的數據庫調用,以及調用的各種細節參數。

      更何況我的工具不止針對SQL Server有效,理論上,.net支持的,我的數據訪問層應該都支持。
      前面也說了,它是配合我的數據訪問層一起工作的,
      所以,只要是使用ClownFish哪怕是訪問Access數據庫,也能有這樣的監控效果。(前面有圖片證明)

      關于示例代碼

      為了能讓更多的人選擇ClownFish,這次我為大家準備了大量的示例代碼。

      1. ClownFishDEMO是一個綜合示例,網站型項目。運行效果圖:

      2. MultiAccountDEMO是一個多帳套的演示網站。演示了一套代碼處理多帳套的功能。

      3. PerformanceTestApp是前面介紹的性能測試項目,你也可以將其它的數據訪問層加入其中,一起做性能測試。

      不僅僅是以上三個項目演示了如何使用ClownFish, 我還為以前的 MyMVC框架 的示例程序增加了數據庫訪問功能(以前只支持XML文件)。
      現在,MyMVC框架 的演示程序也能通過ClownFish來訪問SQLSERVER。
      可以修改 MyMVC框架 演示網站中的web.config來切換數據訪問方法:

      <appSettings>
          <!--DataSoureceKind 表示不同的數據訪問方式,目前支持三個可選的配置值(注意大小寫):
              1. XmlFile ,表示使用XML文件中的數據,此選項為默認值。
              2. XmlCommand ,表示使用配置文件中的SQL命令去訪問SQLSERVER
              3. StoreProcedure ,表示調用SQLSERVER中的存儲過程去訪問數據庫
              你可以修改下面的配置,并結合ClownFishSQLProfiler.exe工具去觀察它們的差別。        
          -->
          <add key="DataSoureceKind" value="XmlFile" />
      </appSettings>
      

      考慮到有些人在配置SQLSERVER時,會遇到一些問題,MyMVC框架的演示程序仍然默認使用XML文件,而不是SQLSERVER數據庫。

      但是,由于ClownFish是一個數據訪問層,它的示例只能訪問數據庫了。
      如果不知道如何配置示例, 請參考我的博客:如何在IIS6,7中部署ASP.NET網站

      還有一件讓我憂慮的事情:示例中還演示了 MySql的訪問!
      我建議:如果你平時不使用MySql,那么就跳過示例中的MySql演示部分吧。

      最后建議:在下載示例代碼后,首先打開 Readme.txt 文件看一下,謝謝!


      如果需要了解ClownFish的使用方法,請點擊ClownFish 使用說明

      點擊此處下載示例代碼(ClownFishDEMO)

      點擊此處下載示例代碼(MyMVC)

      posted on 2012-07-17 08:26  Fish Li  閱讀(69358)  評論(318)    收藏  舉報
      主站蜘蛛池模板: 青草热在线观看精品视频| 成A人片亚洲日本久久| 苍井空一区二区三区在线观看| 久久一日本道色综合久久| 人人妻人人澡人人爽人人精品av| 久久精品夜夜夜夜夜久久| 少妇人妻偷人精品免费| 亚洲色大成网站WWW尤物| 都匀市| 国内自拍视频在线一区| 亚洲国产精品综合一区二区| 国产首页一区二区不卡| 国产成人不卡一区二区| 国产精品国产高清国产av| 波多野结系列18部无码观看AV| 午夜家庭影院| 91久久亚洲综合精品成人| 国产精品多p对白交换绿帽| 欧美日韩v| 男人猛躁进女人免费播放| 精品一区二区三区四区色| 99无码中文字幕视频| 日韩加勒比一本无码精品| 国产无遮挡又黄又爽不要vip软件| 久久久久久久波多野结衣高潮| 博乐市| 日本精品极品视频在线| AV极品无码专区亚洲AV| 孝感市| 亚洲国产精品一区二区第一页| 人妻少妇456在线视频| 文成县| 久久综合色之久久综合色| 日本高清无卡码一区二区| 日韩激情一区二区三区| 五月丁香六月狠狠爱综合| 国产一区二区三中文字幕| 狠狠v日韩v欧美v| 成人午夜视频一区二区无码 | 我国产码在线观看av哈哈哈网站| 国产精品嫩草99av在线|