LINQ 內連線和左外連線

2021-10-01 17:06:33 字數 3935 閱讀 9406

使用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...