如何做到SQL Distinct取出不重覆資料的效果

如何做到像Sql的Distinct取出不重覆資料的功能,除了.Net 2.x以上可以用DataTable.DefaultView.ToTable外,那.Net 1.x要怎麼辦.

Sql的語法可以做到Distinct的功能,取出不重覆的資料來,但如果不是從DB取資料,來源可能是DataTable,那要怎麼辨?

之前Google了一下,找到了Topcat分享的技術[ 如何從DataTable中取出Distinct的資料 ],果然簡單又有效率.

tmpDataTable.DefaultView.ToTable(true,"唯一的欄位名");

這麼一行就可以取得tmpDataTable裡不重覆的資料,果然是很簡單的好東西.

但一定也有不少人事後跟我有一樣的反應.....

什麼!!!!只有.Net 2.0以上才有!!! 那麼1.X的怎麼辨??

要做也不是不能做,就跑跑迴圈去做囉,不過最近看到一個有趣的做法,可以應用在某些狀況下. 當然這個在.Net 1.x也可以用.

 

首先在PageLoad的地方塞入一些資料Demo用.

        DataTable dt = new DataTable("TestDT");
        private void Form1_Load(object sender, EventArgs e)
        {
            dt.Columns.Add("Loc");
            for (int i = 0; i < 15; i++)
            {
                DataRow dr = dt.NewRow();
                dr["Loc"] = new Random(i).Next(10);
                dt.Rows.Add(dr);
            }

            dataGridView1.DataSource = dt;
        }

 

再來就加一個Function,這個Function就是這次的主角,傳入兩個參數,一個是存著全部資料的DataTable,另一個就是要Distinct的欄位,回傳的string陣列就是Distinct的清單,這個Sample Code是在MSDN上看到的,不過有個地方不是很好,"老師"有教過,不要拿Try-Catch來做資料正確的判斷,這樣的效能很差,所以呢,就小改了一下,加上了第8行,看有沒有重覆的Key,沒有再Add進去.

01         public string[] GetDistinctValues(DataTable dtable, string colName)
02         {//FYI : http://msdn.microsoft.com/zh-cn/library/system.data.datatable.defaultview(VS.80).aspx
03             Hashtable hTable = new Hashtable();
04             foreach (DataRow drow in dtable.Rows)
05             {
06                 try
07                 {
08                     if (!hTable.ContainsKey(drow[colName]))//判斷是否有重覆的Key
09                     {
10                         hTable.Add(drow[colName], string.Empty);
11                     }

12                 }

13                 catch (Exception ex)//MSDN是用Try-Catch的Error去限制唯一Key,效能會很差,這裡不這麼用,只用來判斷其它錯誤.
14                 {
15                     MessageBox.Show(ex.Message);
16                 }

17             }

18             string[] objArray = new string[hTable.Keys.Count];
19             hTable.Keys.CopyTo(objArray, 0);
20             return objArray;
21         }

接下來就是要呼叫這個Function囉,第一行就是呼叫它,回傳string array到tmp變數內,後續就把它放到DataTable裡,用dataGridView去show出來.

01             string[] tmp = GetDistinctValues(dt, "Loc");
02             DataTable tmpdt = new DataTable("TestDT");//將Distinct的結果放到新的DataTable
03             tmpdt.Columns.Add("Loc");
04             foreach (string s in tmp)
05             {
06                 DataRow dr = tmpdt.NewRow();
07                 dr["Loc"] = s;
08                 tmpdt.Rows.Add(dr);
09             }

10             dataGridView1.DataSource = tmpdt;

這個用法很有趣,沒什麼特別的技術,但卻是一個之前沒想到的簡單邏輯,或許有人會說,有這唯一的Key沒有用啊,沒有其它資訊,換個方式想,可以用DataView.RowFilter或是DataTable.Select,用這Key就可以取得資料了.

.Net 1.x的用法沒有2.X以上的簡潔好用,但也算是不是方法的方法.

 

參考資料 :

MSDN DataView.RowFilter 屬性

MSDN DataTable.Select 方法

MSDN DataTable.DefaultView屬性