首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

LINQ to DataSet 完整指南:離線資料查詢與轉換橋樑

     編輯:關於.NET

定位與核心組件

LINQ to DataSet 專為離線資料 (DataSet/DataTable) 設計,屬於 LINQ to ADO.NET 子集。核心擴充方法集中在兩個靜態類別:

  • System.Data.DataTableExtensions:DataTable、DataView、IEnumerable<DataRow> 互轉。
  • System.Data.DataRowExtensions:強型別欄位存取 Field<T>() / SetField<T>()。

DataTableExtensions:三大轉換橋樑

方法用途
AsEnumerable()DataTable → EnumerableRowCollection<DataRow> (實作 IEnumerable<DataRow>),啟用 LINQ 查詢
AsDataView()DataTable 或查詢結果 → DataView,支援資料繫結
CopyToDataTable()查詢結果 (IEnumerable<DataRow>) → 新 DataTable 或合併至現有 Table

CopyToDataTable 進階選項

// 無參數:自動建立 Original/Current 版本
var newTable = query.CopyToDataTable();

// 帶 LoadOption:控制版本建立行為
query.CopyToDataTable(targetTable, LoadOption.OverwriteChanges); // 更新 Current + Original
query.CopyToDataTable(targetTable, LoadOption.PreserveChanges);  // 僅更新 Original
query.CopyToDataTable(targetTable, LoadOption.Upsert);           // 僅更新 Current

關鍵:合併時必須設定目標 Table PrimaryKey,否則僅單純 Append。

DataRowExtensions:強型別欄位存取

// 讀取:支援 Column、Index、Name、版本
string name = row.Field<string>("Name");
string nameOrig = row.Field<string>("Name", DataRowVersion.Original);

// 寫入:自動處理 null → DBNull.Value
row.SetField<string>("Name", null); // 自動轉為 DBNull.Value

優勢:

  • 強型別,免拆箱/轉型。
  • 自動處理 DBNull.Value ⇄ null 雙向轉換(Field 讀取 DBNull 回傳 null;SetField 寫入 null 存 DBNull)。
  • 避免 DBNull 轉型拋例外。

集合運算必須使用 DataRowComparer.Default

Distinct、Union、Except、Intersect、SequenceEqual 預設用參考比較,導致內容相同但非同一物件的 DataRow 視為不同。必須傳入 DataRowComparer.Default 進行值比較(先比欄位數,再逐欄位 Equals)。

完整範例:從建立到查詢、修改、合併、去重

public static void Test() {
    var students = new[] {
        new Student { Id = 1, Name = "Lazy Bee" },
        new Student { Id = 7, Name = "Flying Wind" },
        new Student { Id = 13, Name = "PiPi Zhu" },
        new Student { Id = 72, Name = "Chong Chong" }
    };
    DataTable originalTable = GetDataTable(students);

    // 1. 原始表無 Original 版本,存取拋例外
    // 2. 用 CopyToDataTable 建立版本
    DataTable newTable = originalTable.AsEnumerable().CopyToDataTable();

    // 3. 修改資料
    newTable.AsEnumerable()
        .Single(r => r.Field<string>("Name") == "PiPi Zhu")
        .SetField("Name", "George Oscar Bluth");

    // 4. 設 null
    newTable.AsEnumerable()
        .Single(r => r.Field<int>("Id") == 13)
        .SetField<string>("Name", null);

    // 5. 合併回原表(需 PrimaryKey)
    originalTable.PrimaryKey = new[] { originalTable.Columns["Id"] };
    newTable.AsEnumerable().CopyToDataTable(originalTable, LoadOption.OverwriteChanges);

    // 6. 去重(必須用 DataRowComparer.Default)
    var distinct = originalTable.AsEnumerable().Distinct(DataRowComparer.Default);
}

五大注意事項總結

  1. 集合運算:Distinct/Union/Except/Intersect/SequenceEqual、GroupBy Key 為 DataRow 時,必須用 DataRowComparer.Default。
  2. SetField:寫入 null 自動轉 DBNull.Value。
  3. Field:讀取 DBNull.Value 自動回傳 null,強型別免拆箱。
  4. Original 版本:預設不存在,存取拋例外。解決:AcceptChanges()、CopyToDataTable()、或先 HasVersion 判斷。
  5. CopyToDataTable 合併:必須設 PrimaryKey,否則僅 Append。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved