优雅的合并两个DataTable
根据某列合并
这里我们只利用.Net 的LINQ语句进行的Join查询,当数据量过大是会明显的比用for循环拼接快得多。
如果大家还有更好的方法欢迎留言讨
static void DemonstrateMergeTable()
{
DataTable table1 = new DataTable("Items");
// 添加列
DataColumn idColumn = new DataColumn("id", typeof(System.String));
DataColumn itemColumn = new DataColumn("item", typeof(System.Int32));
table1.Columns.Add(idColumn);
table1.Columns.Add(itemColumn);
// 设置主键
table1.PrimaryKey = new DataColumn[] {
idColumn };
// 为表添加RowChanged事件处理程序。
table1.RowChanged += new
System.Data.DataRowChangeEventHandler(Row_Changed);
// 添加十行。
DataRow row;
for (int i = 0; i <= 9; i++)
{
row = table1.NewRow();
row["id"] = i.ToString();
row["item"] = i;
table1.Rows.Add(row);
}
// 接受改变。
table1.AcceptChanges();
PrintValues(table1, "Original values");
// 创建与第一个完全相同的第二个数据表。
DataTable table2 = table1.Clone();
//给第二个dataTable添加一列和第一个datTable不同的一列
table2.Columns.Add("newColumn", typeof(System.String));
//这里添加三列
row = table2.NewRow();
row["id"] = "1";
row["item"] = 774;
row["newColumn"] = "new column 1";
table2.Rows.Add(row);
row = table2.NewRow();
row["id"] = "2";
row["item"] = 555;
row["newColumn"] = "new column 2";
table2.Rows.Add(row);
row = table2.NewRow();
row["id"] ="3";
row["item"] = 665;
row["newColumn"] = "new column 3";
table2.Rows.Add(row);
// 利用Linq关联两个DaTable,根据id列进行合并
//这里需要注意的是如果DataTable2中有某一列而DataTable1中没有的话就需要做NUll判断。
var query = from t_2 in table2.AsEnumerable()
join t_1 in table1.AsEnumerable() on t_2.Field<string>("id") equals t_1.Field<string>("id")
select new {
x = t_1["id"], y = t_2 == null ? "" :t_2["newColumn"], z = t_1["item"] };
var data = ToDataTable (query);
foreach ( DataRow item in data.Rows)
{
Console.WriteLine(item["x"]);
Console.WriteLine(item["y"]);
Console.WriteLine(item["z"]);
}
}
//Linq查询出来的数据是IEnumerable类型的,这里我们利用此方法将类型转为DataTable.
static DataTable ToDataTable<T>(IEnumerable<T> collection)
{
var props = typeof(T).GetProperties();
var dt = new DataTable();
dt.Columns.AddRange(props.Select(p => new DataColumn(p.Name, p.PropertyType)).ToArray());
if (collection.Count() > 0)
{
for (int i = 0; i < collection.Count(); i++)
{
ArrayList tempList = new ArrayList();
foreach (PropertyInfo pi in props)
{
object obj = pi.GetValue(collection.ElementAt(i), null);
tempList.Add(obj);
}
object[] array = tempList.ToArray();
dt.LoadDataRow(array, true);
}
}
return dt;
}
//这个方法是监听行改变
static void Row_Changed(object sender,
DataRowChangeEventArgs e)
{
Console.WriteLine("Row changed {0}\t{1}", e.Action,
e.Row.ItemArray[0]);
}
//打印daTable中的数据
static void PrintValues(DataTable table, string label)
{
// Display the values in the supplied DataTable:
Console.WriteLine(label);
foreach (DataRow row in table.Rows)
{
foreach (DataColumn col in table.Columns)
{
Console.Write("\t " + row[col].ToString());
}
Console.WriteLine();
}
}
//调用主方法
DemonstrateMergeTable();