iT邦幫忙

0

C# LINQ 要如何改成left join

  • 分享至 

  • xImage

之前做報表的時候沒有注意到LINQ的JOIN是INNER,現在想要把它改成LEFT JOIN
現在有兩個資料表,A、B
假設其中
A有a1,a2,a3三個欄位,並且有20筆資料
B有b1,b2,b3三個欄位,並且有10筆資料
進行關聯的欄位是a1=b1、a2=b2

進行實驗的程式碼如下(使用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, 20))
{
	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, 10))
{
	var row2 = dt2.NewRow();
	row2.SetField("Id", i);
	row2.SetField("No", 10 + i);
	row2.SetField("Count", 1000 + i );

	dt2.Rows.Add(row2);
}

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 { 
						 id=s.Field<int>("Id"),
						 no=s.Field<int>("No"),
						 Count=s.Field<int?>("Count").ToString(),
						 name=c.Field<string>("Name")
                         };
result.Dump();						 
result.ToString();

我的目標是A表的a3欄位所以資料都可以顯示出來,麻煩各位高手指點!!感謝

powerc iT邦研究生 5 級 ‧ 2022-08-23 11:51:57 檢舉
lambda表達式的GroupJoin應該就是你要的LEFT JOIN
堅持要用linq的話 參考一下官方文件
https://docs.microsoft.com/zh-tw/dotnet/csharp/linq/perform-left-outer-joins
謝謝你的建議,會說用LINQ是因為在C#程式碼中使用查詢是最近才開始,都還不是很熟悉,只是之前是使用LINQ進行多重關聯,才想說繼續沿用
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
w4560000
iT邦研究生 5 級 ‧ 2022-08-23 14:13:47
最佳解答
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, 20))
{
	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, 10))
{
	var row2 = dt2.NewRow();
	row2.SetField("Id", i);
	row2.SetField("No", 10 + i);
	row2.SetField("Count", 1000 + i );

	dt2.Rows.Add(row2);
}

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")} into tmp
						 from s in tmp.DefaultIfEmpty()
                         select new { 
						 id=c.Field<int>("Id"),
						 no=c.Field<int>("No"),
						 Count=s != null ? s.Field<int?>("Count") : null,
						 name=c.Field<string>("Name")
                         };
result.Dump();						 
result.ToString();
0
  var query = (
      from a in listA
      join b in listB on new { fk1 = a.A1, fk2 = a.A2 } equals 
                         new { fk1 = b.B1, fk2 = b.B2 } 
                         into bv
      from c in bv.DefaultIfEmpty()
      select new
      {
          a.A1,
          a.A2,
          a.A3,
          B3 = c != null ? c.B3 : ""
      }).ToList();

https://ithelp.ithome.com.tw/upload/images/20220823/20135969DInKvKwLa7.png

0
wilson1966
iT邦研究生 1 級 ‧ 2022-08-29 09:04:59

LINQ是未來的趨勢,但個人覺得用 LINQ 寫SQL太麻煩了,還是傳統的字串SQL 比較方便,且能應付一堆特殊要求而寫的花式SQL。

主要會用到LINQ是因為會有資料不在資料庫裏面,又想要讓他跟資料庫的資料合併輸出表單,不然我不是很想要用,不太熟悉使用

我要發表回答

立即登入回答