使用join子句可以根據特定的條件合併兩個資料來源,但之前要獲得兩個要連線的列表。在一級方程式比賽中,有賽車手冠軍和車隊冠軍。賽車手從getchampions()方法中返回,車隊從getconstructorchampions()方法中返回。現在要獲得乙個年份列表,列出每年的賽車手冠軍和車隊冠軍。
為此,先定義兩個查詢,用於查詢賽車手和車隊:
static void innerjoin()
;var teams = from t in formula1.getconstructorchampions()
from y in t.years
select new ;
}
有了這兩個查詢,在通過join子句,根據賽車手獲得冠軍的年份和車隊獲得冠軍的年份進行連線。select子句定義了乙個新的匿名型別,它包含year、racer和team屬性。
var racersandteams = (from r in racers
join t in teams on r.year equals t.year
select new ).take(10);
system.console.writeline("year world champion contructor title");
foreach(var item in racersandteams)
: ");
}
當然,也可以把它們合併為乙個linq查詢,但這只是一種個人喜好的問題:
var racersandteams = (from r in
from r1 in formula1.getchampions()
from yr in r1.years
select new
join t in
from t1 in formula1.getconstructorchampions()
from yt in t1.years
select new
on r.year equals t.year
orderby r.year
select new ).take(10);
使用擴充套件方法可以加入賽車手和車隊,具體操作是呼叫join方法,通過第乙個引數傳遞車隊,把它們與賽車手連線起來,指定外部和內部集合的關鍵字選擇器,並通過最後乙個引數定義結果選擇器:
static void innerjoinwithmethods()
"});
var teams = formula1.getconstructorchampions()
.selectmany(t=>t.years,(t1,year)=>
new );
var racersandteams = racers.join(
teams,
r=>r.year,
t=>t.year,
(r,t)=> new ).orderby(item=>item.year).take(10);
}
結果顯示了在同時有了賽車手冠軍和車隊冠軍的前10年中,匿名型別中的資料:
year world champion contructor title
1958: mike hawthorn vanwall
1959: jack brabham cooper
1960: jack brabham cooper
1961: phil hill ferrari
1962: graham hill brm
1963: jim clark lotus
1964: john surtees ferrari
1965: jim clark lotus
1966: jack brabham brabham
1967: denny hulme brabham
左外連線
上乙個連線示例的輸出從2023年開始,因為從這一年開始,才同時有了賽車手冠軍和車隊冠軍。賽車手冠軍出現的更早一些,是在2023年。使用內連線時,只有找到了匹配的記錄才返回結果。為了在結果中包含所有的年份,可以使用左外連線。左外連線返回左邊序列中的全部元素,即使它們在右邊的序列中並沒有匹配的元素。
下面修改前面的linq查詢,使用左外連線。左外連線用join子句和defaultifempty方法定義。如果查詢的左側(賽車手)沒有匹配的車隊冠軍,就使用defaultifempty方法定義其右側的預設值:
static void leftouterjoin()
;var teams = from t in formula1.getconstructorchampions()
from y in t.years
select new ;
var racersandteams = (from r in racers
join t in teams
on r.year equals t.year
into rt
from t in rt.defaultifempty()
orderby r.year
select new ).take(10);
}
通過擴充套件方法執行相同的查詢時,使用groupjoin方法。前三個引數與join相似。但groupjoin的結果是不同的。join方法返回乙個平鋪列表,而groupjoin返回乙個列表,其中第乙個列表中包含的每個匹配項都包含第二個列表中的乙個匹配列表。使用下面的selectmaney方法,列表再次被鋪平。如果沒有匹配的車隊,則constructors屬性就賦予型別的預設值,對類二元,預設值都為空。建立匿名型別時,如果車隊為空,constructors屬性將賦予字串"no constructor championship":
static void leftouterjionwithmethods()
"});
var teams = formula1.getconstructorchampions()
.selectmany(t=>t.years,(t1,year)=>
new );
var racersandteams = (racers.groupjoin(
teams,
r=>r.year,
t=>t.year,
(r,ts)=> new ).selectmany(rt=>rt.constructors.defaultifempty(),
(r,t)=>new )).take(10);
}
用這個查詢執行應用程式,得到的輸出將從2023年開始,如下所示:
year world champion contructor title
1950: nino farina no contructor chanpionship
1952: alberto ascari no contructor chanpionship
1953: alberto ascari no contructor chanpionship
1951: juan manuel fangio no contructor chanpionship
1954: juan manuel fangio no contructor chanpionship
1955: juan manuel fangio no contructor chanpionship
1956: juan manuel fangio no contructor chanpionship
1957: juan manuel fangio no contructor chanpionship
1958: mike hawthorn vanwall
1961: phil hill ferrari
LINQ左外連線
左連線或左外連線 包含左邊的表的所有行,如果右邊表中某行沒有匹配,該行內容為空null。sql語句select from dbo.project left join dbo.voice on dbo.project.voiceid dbo.voice.id 看一下網上的linq語句例子 左連線 va...
Linq to EF 內連線和左外連線
linq中連線主要有組連線 內連線 左外連線 交叉連線四種。本文主要講解沒連線和左外連線。一 內連線 內連線與sql中inner join一樣,即找出兩個序列的交集 內連線 join c in model.course on s.coursecno equals c.cno where c.cno ...
SQL 內連線,外連線(左外連線 右外連線)
參考整理筆記 關鍵字 inner join on 語句 select from a table a inner join b table bon a.a id b.b id 執行結果 說明 組合兩個表中的記錄,返回關聯字段相符的記錄,也就是返回兩個表的交集 陰影 部分。關鍵字 left join o...