2013年4月29日 星期一

ASP.NET 如何對在陣列裡的複雜型態物件使用 Sort

ASP.NET 如何對在陣列裡的複雜型態物件使用 Sort

測試環境
  • OS:Windows 7 64bit
  • IDE:Visual Studio 2010
  • Project Type:Web From Developer
  • Framework: ASP.NET 4

狀況描述:
  • 想要使用Collection系列組件的Sort對複雜形態物件做排序。

解決方式:
  • 使用comparison
實作範例:
  • Dog.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


/// <summary>
/// Dog 的摘要描述
/// </summary>
public class Dog
{
  public Dog(string name=null , int dogID=-1)
  {
    this.Name = name;
    this.DogID = dogID;       
  }

    private string name;
    public string Name 
    {
        get 
        {
            return this.name;
        }
        set 
        {
            if (this.name != value
            {
                this.name = value;
            }
        }
    }

    private int dogID;
    public int DogID 
    {
        get 
        {
            return this.dogID;
        }
        set 
        {
            if (this.dogID != value
            {
                this.dogID = value;
            }
        }
    }
}

  • ObjectSortUT.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using System.Collections;

public partial class ObjectSortUT : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //這個是泛型宣告,這裡是說這個List內只能放Dog型態的物件
        List<Dog> dogs = new List<Dog>();

        //亂數產生器
        Random rd = new Random();

        for (int i = 0; i < 10; i++) 
        {
            //加入一個Dog,傳入兩個數值
            dogs.Add(new Dog( string.Format("小狗{0}",i) , rd.Next(10, 101)));
        }

        string result = "";

        //取得目前List中狗物件的順序
        foreach (Dog dog in dogs) 
        {
            result += string.Format("DogID = {0}     ", dog.DogID);
        }

        //輸出於瀏覽器
        Response.Write(result + "</br>");

        //好了請問該如和使用List的sort排序?

        //請用
        dogs.Sort(coustomerSort);


        //在印一次,我懶得抽函式用copy貼的方便測試
        result = "";
        foreach (Dog dog in dogs)
        {
            result += string.Format("DogID = {0}     ", dog.DogID);
        }

        //輸出於瀏覽器
        Response.Write(result + "</br>");
    }

    //一個針對Dog物件排序的method
    private int coustomerSort(Dog v1 , Dog v2) 
    {
        return Math.Abs(v1.DogID) - Math.Abs(v2.DogID);
    }
}

執行結果:

DogID = 23 DogID = 66 DogID = 32 DogID = 84 DogID = 64 DogID = 94 DogID = 79 DogID = 78 DogID = 38 DogID = 83
DogID = 23 DogID = 32 DogID = 38 DogID = 64 DogID = 66 DogID = 78 DogID = 79 DogID = 83 DogID = 84 DogID = 94 





檔案夾結構:

















後記:
  • 為了程式碼的好維護,通常若是內部有的功能,如非特別需要優化的演算法,大多使用內建函式,因為內建函式也已經做了一定性的優化,通常會比自己寫的排序速度更快,若自己在寫一個bubble sort,會容易發生讓其他為護人員增加維護負擔。

StringBuilder and String 動態字串串接效能測試

StringBuilder 與 String 運行於動態字串串接效能測試

測試環境
  • OS:Windows 7 64bit
  • IDE:Visual Studio 2010
  • Project Type:Web From Developer
  • Framework: ASP.NET 4

MSDN StringBuilder官方說明引用:
  • String 物件是不可變動的。 每次您使用 System.String 類別的其中一個方法時,就會在記憶體中建立新的字串物件,而這需要為這個新物件配置新的記憶體空間。 當您需要重複修改字串時,建立新的 String 物件可能會耗用相當多的資源。 當您只要修改字串,但是不要建立新的物件時,就可以使用System.Text.StringBuilder 類別。 例如,在迴圈中串連多個字串時,使用 StringBuilder 類別可增加效能。

測試範例碼:




using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

//StringBuilder namespace
using System.Text;

//StopWatch namespace
using System.Diagnostics;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        string sg = "";
        StringBuilder sb = new StringBuilder();
       
        //程序計時器
        Stopwatch sw = new Stopwatch();
        
        //loop count 一萬次
        int count = 10000;

        //計時器開始計時
        sw.Start();
        for (int i = 0; i < count; i++) 
        {
            //如同 s += (i + abcdefghijklmnopqrstuvwxyz);
            sb.Append(i);
            sb.Append("abcdefghijklmnopqrstuvwxyz");
        }

        //計時器中止
        sw.Stop();

        //輸出到瀏覽器上,</br是瀏覽器上的斷行>
        //1ms = 0.001秒
        Response.Write ("StringBuilder執行時間" + sw.ElapsedMilliseconds + "ms" + "</br>");

        //計時器重置
        sw.Reset();
        sw.Start();
        for (int j = 0; j < count; j++) 
        {
            sg += j + "abcdefghijklmnopqrstuvwxyz";
        }
        sw.Stop();
        Response.Write("String執行時間" + sw.ElapsedMilliseconds + "ms" + "</br>");
    }
}

輸出結果:

StringBuilder執行時間6ms
String執行時間5108ms


















備註:
  • 但是要注意,若是固定格式的靜態字串,使用StringBuilder反而效能會變差。

參考資料:

Query String

Query String
  • URL URI在?後方的一串參數。
  • 用來傳遞參數。
  • 參數用來給予作資料查詢或是介面上的屬性設定等等。

範例:
  • http://localhost:61537/WebSite1/Default.aspx?id=1234456
    ?後方那串就是Query String,Query String可以帶多個,直到GET傳遞規範大小。
  • Query String 走的是 HTTP GET 傳輸協定。
  • HTTP GET 就是使用 網址 + Query String
  • 在IE中統一資源定位器 (URL) 長度限制在 2083 Byte,因此 網址 + Query String不可以超過2083 Byte。
  • RFC 2616、 「 超文字傳輸通訊協定--HTTP/1.1 中,"未指定任何 URL 長度的需求。

  • 要注意的是雖然IE的URL有2083Byte的大小限制,但是FireFox與Chrome等都不相同,實際上要查尋各家瀏覽器的文件或是以程式做測試才能知道實際大小,原因是RFC 2616制訂協定中並無規範URL長度,但各家瀏覽器在實作時都會有所不同。

參考資料:

網站與專案的差異

ASP.NET 網站與專案的差異


  • 專案,會將方案內所有的程式編譯成一隻DLL與執行檔,當其中一隻程式變動就要重新編譯所有的內容,開發上較維護上較不方便。
  • 網站,第一次開啟時會線上編譯,所以除了第一個開啟的人速度較慢,之後沒有差異,在開發維護上較方便,只需上傳修改掉的檔案即可。

  • 原本使用DLL檔的用意是想提升安全,但是其實ASP.NET的DLL檔是可以被反組譯看到原始碼(Source Code),而且顧客都是要Source Code,所以使用專案意義不大。

練習加入資料庫檔案項目


開發環境
  • OS:Windows 7 64bit
  • IDE: Visual Studio 2010
  • Project Type:WebForm Developer
  • Framework: ASP.NET 4

狀況描述:
  • 想在Web Site中加入SQL資料庫檔案項目,並以GridView測試連接。
實作步驟:
  • 加入App_Data資料夾。網站滑鼠右鍵  →   加入(D)  →  加入ASP.NET 資料夾(S)  →  App_Data(A)。












      • 加入SQL Server資料庫。
        網站滑鼠右鍵  →   加入(D)  →  加入新增項目(W)  →  Visual C#  →  SQL Server資料庫。


















      • 連接資料庫
        對所選到的資料庫按下重新整理即可連接。


















      • 加入新的資料表
         我們將加入三張資料表如下:
          Customers(客戶)
          Products(產品)
          Orders(訂單)

        在資料表 → 滑鼠右鍵 → 加入新的資料表。

      • Cutomers 資料表建立
         在TSQL中記得把名稱改為TblCustomer ,這是表格建立名稱。
         在 [CustomerID] INT NOT NULL PRIMARY KEY IDENTITY, PRIMARY KEY
           是定義為主鍵,IDENTITY是自動編號。

      CREATE TABLE [dbo].[TblCustomers]
      (
          [CustomerID] INT NOT NULL PRIMARY KEY IDENTITY
          [Name] NVARCHAR(50) NOT NULL, 
          [PhoneNumber] VARCHAR(12) NOT NULL, 
          [Address] NVARCHAR(50) NOT NULL
      )
















      編輯完畢後按下更新(U),即可建立資料表。




      • Products 資料表建立
      CREATE TABLE [dbo].[TblProducts]
      (
         [ProductID] INT NOT NULL PRIMARY KEY IDENTITY
         [Name] NVARCHAR(50) NOT NULL, 
         [Price] DECIMAL NOT NULL
      )

      • Orders 資料表建立
      CREATE TABLE [dbo].[TblOrders]
      (
          [OrdersID] INT NOT NULL PRIMARY KEY IDENTITY
          [CustomerID] INT NOT NULL, 
          [ProductID] INT NOT NULL, 
          [Quantity] INT NOT NULL, 
          CONSTRAINT [FK_TblOrders_TblCostomers] FOREIGN KEY (CustomerID) REFERENCES [TblCustomers](CustomerID), 
          CONSTRAINT [FK_TblOrders_TblProducts] FOREIGN KEY ([ProductID]) REFERENCES [TblProducts]([ProductID]) 
      )

      • 建立資料
         在目標資料表上按下滑鼠右鍵顯示資料表資料(S),即可開啟編輯視窗。




































      • 建立一個新網頁 Default.aspx
         網站滑鼠右鍵  →   加入(D)  →  加入新增項目(W)  → Visual C# → WebFrom
      • 工具箱中分類資料中找到GridView拖曳到Default.aspx畫面中
         記得Default.aspx要切換到設計。
         GridView是在工具箱中的資料分類中。
















      • 將sqlDataSource拖曳到Default.aspx畫面中
         選擇sqlDataSource設定資料來源










         選擇一開始建立的資料庫檔名稱Database.mdf
         



















        設定Select陳述式中,先選擇你的來源資料表TblCoustomers然後將你的欄位全部勾選




















        按下進階勾選 產生INSERT、UPDATE 和 DELETE 陳述式(G)選項 並按下確定。

















        按下測試查詢,測驗資料撈取運作正確與否。




















      • GridView中設定資料來源為sqlDataSource1
















      • 執行Default.asp












      以此類推可以做好其他兩個資料表即可完成練習