摘要:LINQ - DataTable 與 List
這段時間很緩慢的持續看著 LINQ 的書籍,腦袋轉了一下覺得似乎沒有寫過 DataTable 轉 List<TResult>,或者是 List<TResult> 轉 DataTable 的轉換。若能寫出來的話,或許對日後自己所負責的專案有所幫助吧。其實實作後您就會發現,都是在玩「反映 (Reflection)」,以下就來看看唄...
步驟一:建立一個新的專案後,隨後在建立一個名為「DataTableAndListExtensions.cs」Class
步驟二:撰寫 DataTable To List<TResult> 與 List<TResult> To DataTable 的程式碼
Code:
using System.Data;
using System.Reflection;
using System.Collections;
namespace DataTableAndListInterchangeSample
{
public static class DataTableAndListExtensions
{
public static DataTable ListToDataTable<TResult>(this IEnumerable<TResult> ListValue) where TResult : class, new()
{
//建立一個回傳用的 DataTable
DataTable dt = new DataTable();
//取得映射型別
Type type = typeof(TResult);
//宣告一個 PropertyInfo 陣列,來接取 Type 所有的共用屬性
PropertyInfo[] PI_List = null;
foreach (var item in ListValue)
{
//判斷 DataTable 是否已經定義欄位名稱與型態
if (dt.Columns.Count == 0)
{
//取得 Type 所有的共用屬性
PI_List = item.GetType().GetProperties();
//將 List 中的 名稱 與 型別,定義 DataTable 中的欄位 名稱 與 型別
foreach (var item1 in PI_List)
{
dt.Columns.Add(item1.Name, item1.PropertyType);
}
}
//在 DataTable 中建立一個新的列
DataRow dr = dt.NewRow();
//將資料足筆新增到 DataTable 中
foreach (var item2 in PI_List)
{
dr[item2.Name] = item2.GetValue(item, null);
}
dt.Rows.Add(dr);
}
dt.AcceptChanges();
return dt;
}
public static List<TResult> DataTableToList<TResult>(this DataTable DataTableValue) where TResult : class, new()
{
//建立一個回傳用的 List<TResult>
List<TResult> Result_List = new List<TResult>();
//取得映射型別
Type type = typeof(TResult);
//儲存 DataTable 的欄位名稱
List<PropertyInfo> pr_List = new List<PropertyInfo>();
foreach (PropertyInfo item in type.GetProperties())
{
if (DataTableValue.Columns.IndexOf(item.Name) != -1)
pr_List.Add(item);
}
//足筆將 DataTable 的值新增到 List<TResult> 中
foreach (DataRow item in DataTableValue.Rows)
{
TResult tr = new TResult();
foreach (PropertyInfo item1 in pr_List)
{
if (item[item1.Name] != DBNull.Value)
item1.SetValue(tr, item[item1.Name], null);
}
Result_List.Add(tr);
}
return Result_List;
}
}
}
步驟三:在 WinForm 當中驗證
Code:
namespace DataTableAndListInterchangeSample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class TestClass
{
public string uName { get; set; }
public DateTime uDateTime { get; set; }
}
private void Form1_Load(object sender, EventArgs e)
{
List<TestClass> DataList = new List<TestClass>()
{
new TestClass
{
uName = "Danny",
uDateTime = DateTime.Now
},
new TestClass
{
uName = "Peggy",
uDateTime = DateTime.Now.AddDays(1)
}
};
DataTable dt = DataList.ListToDataTable<TestClass>();
string f_str = string.Empty;
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
if (string.IsNullOrEmpty(f_str))
f_str = dt.Rows[i][j].ToString();
else
f_str += "\r\n" + dt.Rows[i][j].ToString();
}
}
MessageBox.Show(f_str, "系統:List To DataTable", MessageBoxButtons.OK, MessageBoxIcon.Information);
f_str = string.Empty;
List<TestClass> aaa = dt.DataTableToList<TestClass>();
foreach (var item in aaa)
{
f_str += item.uName + "\r\n" + item.uDateTime + "\r\n";
}
MessageBox.Show(f_str, "系統:DataTable To List", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
結果:
參考:
Linq:轉換成 DataTable
擴展方法(1) DataTable 和List 相互轉換
反映 (C# 程式設計手冊)
Reflection in C#
Reflection技術應用