iT邦幫忙

0

C# Dataset進行relations 想要多欄位關聯

  • 分享至 

  • xImage

如題
我現在在C#中有從SQL Server抓的資料和自己上傳的EXCEL資料Datatable_A跟Datatable_B
欄位分別為
Datatable_A
https://ithelp.ithome.com.tw/upload/images/20220728/20150178PUYVMiulNt.png
Datatable_B
https://ithelp.ithome.com.tw/upload/images/20220728/20150178C8TW89nWM2.png

我現在想要把兩張Datatable做關聯,要關聯的欄位是單別、單號、序號,但是我發現C#的DataSet.Relations.Add好像只能用一個參數。

想請問有沒有辦法做多欄位關聯,謝謝各位!!
第一次發文,有錯請見諒!

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
水無痕
iT邦新手 3 級 ‧ 2022-07-29 08:06:49
最佳解答

參考這個解答
https://stackoverflow.com/questions/12955766/how-do-i-define-a-datarelation-between-a-datasets-datatables-on-multiple-column

我用 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();						 
						 
水無痕 iT邦新手 3 級 ‧ 2022-08-04 11:27:04 檢舉

型別問題 ...

c = s.Field<int?>("Count")

原來如此!!非常感謝!!

1
w4560000
iT邦研究生 5 級 ‧ 2022-07-28 11:36:15

可以把 dataTable 再轉成 Enumerable 用 Linq Join資料比較方便

好的,我再去試試看,非常感謝!!!

我要發表回答

立即登入回答