如題
我現在在C#中有從SQL Server抓的資料和自己上傳的EXCEL資料Datatable_A跟Datatable_B
欄位分別為
Datatable_A
Datatable_B
我現在想要把兩張Datatable做關聯,要關聯的欄位是單別、單號、序號,但是我發現C#的DataSet.Relations.Add好像只能用一個參數。
想請問有沒有辦法做多欄位關聯,謝謝各位!!
第一次發文,有錯請見諒!
我用 Linqpad 寫的範例:
var ds = new DataSet();
ds.Tables.Add("dt1");
var dt1 = ds.Tables["dt1"];
dt1.Columns.Add("Id", typeof(int));
dt1.Columns.Add("No", typeof(int));
dt1.Columns.Add("Name", typeof(string));
foreach (var i in Enumerable.Range(1, 5))
{
var row1 = dt1.NewRow();
row1.SetField("Id", i);
row1.SetField("No", 10 + i);
row1.SetField("Name", "Name" + (char)(i + 64));
dt1.Rows.Add(row1);
}
ds.Tables.Add("dt2");
var dt2 = ds.Tables["dt2"];
dt2.Columns.Add("Id", typeof(int));
dt2.Columns.Add("No", typeof(int));
dt2.Columns.Add("Count", typeof(int));
foreach (var i in Enumerable.Range(1, 5))
{
var row2 = dt2.NewRow();
row2.SetField("Id", i);
row2.SetField("No", 10 + i);
row2.SetField("Count", 1000 + i );
dt2.Rows.Add(row2);
}
ds.Dump();
var dtRelation = new DataRelation("processData",
new DataColumn[] { ds.Tables["dt1"].Columns["Id"], ds.Tables["dt1"].Columns["No"] },
new DataColumn[] { ds.Tables["dt2"].Columns["Id"], ds.Tables["dt2"].Columns["No"] }
);
ds.Relations.Add(dtRelation);
ds.Tables["dt1"].Rows[0].Dump("dt1");
ds.Tables["dt1"].Rows[0].GetChildRows(dtRelation).Dump("dt1 childrows");
後來又遇到說,因為有欄位是空值,所以會有問題,我的資料表示要連空值的欄位也抓取,不能把它篩選掉
我也用了linqpad寫了一個實驗用的程式碼,如下
var ds = new DataSet();
ds.Tables.Add("dt1");
var dt1 = ds.Tables["dt1"];
dt1.Columns.Add("Id", typeof(int));
dt1.Columns.Add("No", typeof(int));
dt1.Columns.Add("Name", typeof(string));
foreach (var i in Enumerable.Range(1, 5))
{
var row1 = dt1.NewRow();
row1.SetField("Id", i);
row1.SetField("No", 10 + i);
row1.SetField("Name", "Name" + (char)(i + 64));
dt1.Rows.Add(row1);
}
ds.Tables.Add("dt2");
var dt2 = ds.Tables["dt2"];
dt2.Columns.Add("Id", typeof(int));
dt2.Columns.Add("No", typeof(int));
dt2.Columns.Add("Count", typeof(int));
foreach (var i in Enumerable.Range(1, 5))
{
var row2 = dt2.NewRow();
row2.SetField("Id", i);
row2.SetField("No", 10 + i);
row2.SetField("Count", 1000 + i );
dt2.Rows.Add(row2);
}
var row3 = dt1.NewRow();
row3.SetField("Id", 8);
row3.SetField("No", 10 + 8);
dt1.Rows.Add(row3);
var row4 = dt2.NewRow();
row4.SetField("Id", 8);
row4.SetField("No", 10 + 8);
dt2.Rows.Add(row4);
dt1.Dump();
dt2.Dump();
var result = from c in dt1.AsEnumerable()
join s in dt2.AsEnumerable()
on new { s1=c.Field<int>("Id") , s2=c.Field<int>("No")}
equals
new { s1=s.Field<int>("Id"),s2=s.Field<int>("No")}
select new { a=s.Field<int>("Id"),b=s.Field<int>("No"),c=s.Field<int>("Count")
};
result.Dump();
型別問題 ...
c = s.Field<int?>("Count")
原來如此!!非常感謝!!
可以把 dataTable 再轉成 Enumerable 用 Linq Join資料比較方便