LINQ 與資料存取 (3) - 透過 LINQ 轉換 DataSet 形成可序列化資料

即便 .NET 版號已發展至 4.5 版,而 EF 等資料框架也已釋出相當時日,不過,無論是舊系統的維護,或是為了彈性設計的理由,使用傳統 ADO.NET 存取資料庫,並透過自行設計的資料類別公開資料的方式亦多有所在,在這種情形下,若是要將所取得的 DataSet 資料直接丟到網路上,會碰上一些麻煩,這其中最主要的問題在於序列化的部份,相關的資料必須再經過轉換之後才能被分解送入網路,而這可以透過 LINQ 來完成。

LINQ 與資料存取(1)(2)中我們看到了最簡單的 ADO.NET 與 LINQ 示範了,延續相同的資料來源,現在我們為 Categories 資料表建立一個對映的資料類別如下:

[DataContract(Name = "Categories")]
public class Category
{
    public Category(string id, string name, string description)
    {
        if (  id != null)
        {
            this.id = id;
            this.name = name;
            this.description = description;
        }
    }
    [DataMember(Name = "id")]
    public string id { get; set; }
    [DataMember(Name = "name")]
    public string name { get; set; }
    [DataMember(Name = "description")]
    public string description { get; set; }
}

完成之後,接下來就可以利用 LINQ 進行資料的萃取與轉換,考慮以下的 SQL敘述:

string sql = "SELECT * FROM Categories ";

這段 SQL 取回整個 Categories 資料表的內容,當然,你可以根據需要建立自己的 SQL 敘述,最後我們取得的將是一個 DataSet 物件,以下式將其中真正儲存資料資料表取出:

DataTable table = ds.Tables[0];

取得DataTable 物件實體之後,ADO.NET 的部份就結束了,現在開始轉換資料。我們希望最後這些資料可以形成 Category 物件的集合,因此透過 LINQ 語法進行實作如下:

IEnumerable<Category> c = from t in table.AsEnumerable()
                               select new Category(
                                   t.Field<int>("CategoryID").ToString(),
                                   t.Field<string>("CategoryName"),
                                   t.Field<string>("Description")) { };

好了,這一段語法將我門需要的資料格式轉換完成,透過 SQL 取出的 DataTable 資料,現在已經轉換成為 Category 型態物件組成的IEnumerable 集合了。

LINQ 幾乎已經成了.NET平台的通用資料處理技術了,特別是進入 MVC 、WebAPI 的時代,沒有 LINQ ,你將很難處理複雜的資料運算流程,甚至進入HTML5的世界,與.NET平台的溝通,都需要這個技術作橋樑。

該系列文章將陸續討論相關的議題,也歡迎參加我們 12.8(六)的 《LINQ專業解構 II》,在這個課程當中,學員將會徹底瞭解 LINQ 這項 .NET 平台最重要的資料處理技術。



4 則留言:

匿名 提到...

dear 呂老師:
在練習LINQ時,遇到一個困難。
我已經建立了DataClasses.dbml的App_Code目錄中的文件,頁面上我使用DataClassesDataContext的映射的資料庫,並使用LINQ查詢來填充的資料。
重點在於,local端運行是沒有問題的可以成功抓到資料庫的資料,但在伺服器端執行會出錯:

CS0246: 找不到型別或命名空間名稱 'DataClassesDataContext' (您是否遺漏 using 指示詞或組件參考?)

找了很多資料,都說要加入參考,但該加的都加了,還是一樣不行。
在國外的網站上有看到與我相同的問題,但沒看到有解決方案。
請問老師我該往哪個方向去解決問題?

康廷數位文教網 提到...

你可以追一下這個討論串哦:

http://stackoverflow.com/questions/4299489/cs0012-the-type-system-data-linq-datacontext-is-defined-in-an-assembly-that-i

匿名 提到...

請問一下呂老師
[DataContract]、[DataMember]這兩個是做甚麼用的呢?
感覺有沒有加好像沒差別?

康廷數位文教網 提到...

可以看一下這個討論串哦:

http://social.msdn.microsoft.com/Forums/en-CA/wcf/thread/3a761daf-19e5-42dd-810f-5e4eb0739a4d