C#程式設計 LINQ查詢
LINQ查詢表示式
約束
LINQ查詢表示式必須以from子句開頭,以select或group子句結束
關鍵字
from...in...:指定要查詢的資料以及範圍變數,多個from子句則表示從多個數據源查詢資料。注意:C#編譯器會把"複合from子句"的查詢表示式轉換為SelectMany()擴充套件方法
join...in...on...equals...:指定多個數據源的關聯方式
let:引入用於儲存查詢表示式中子表示式結果的範圍變數,通常能達到層次感會更好,使程式碼更易於月的
orderby、descending:指定元素的排序欄位和排序方式,當有多個排序欄位時,由欄位順序確定主次關係,可指定升序和降序兩種排序方式
where:指定元素的篩選條件,多個where子句則表示了並列條件,必須全部都滿足才能入選,每個where子句可以使用&&、||連線多個條件表示式
group:指定元素的分組欄位
select:指定查詢要返回的目標資料,可以指定任何型別,甚至是匿名型別(目前通常被指定為匿名型別)
into:提供一個臨時的識別符號,該識別符號可以引用join、group和select子句的結果。(1)直接出現在join子句之後的into關鍵字會被翻譯為GroupJoin。(2)select或group子句字後的into它會重新開始一個查詢,讓我們可以繼續引入where、orderby和select子句,它是對分步構建查詢表示式的一種簡寫方式。
下面通過一個案例來學習對兩張表進行查詢
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _013_LINQ { /// <summary> /// 武林高手 /// </summary> class MartialArtsMaster { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Menpai { get; set; } public string Kongfu { get; set; } public int Level { get; set; } public override string ToString() { return string.Format("Id: {0}, Name: {1}, Age: {2}, Menpai: {3}, Kongfu: {4}, Level: {5}", Id, Name, Age, Menpai, Kongfu, Level); } } }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _013_LINQ {
/// <summary>
/// 武學
/// </summary>
class Kongfu {
public int Id { get; set; }
public string Name { get; set; }
public int Power { get; set; }
public override string ToString()
{
return string.Format("Id: {0}, Name: {1}, Power: {2}", Id, Name, Power);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace _013_LINQ
{
internal class Program
{
private static void Main(string[] args)
{
//初始化武林高手
var masterList = new List<MartialArtsMaster>()
{
new MartialArtsMaster() {Id = 1, Name = "黃蓉", Age = 18, Menpai = "丐幫", Kongfu = "打狗棒法", Level = 9},
new MartialArtsMaster() {Id = 2, Name = "洪七公", Age = 70, Menpai = "丐幫", Kongfu = "打狗棒法", Level = 10},
new MartialArtsMaster() {Id = 3, Name = "郭靖", Age = 22, Menpai = "丐幫", Kongfu = "降龍十八掌", Level = 10},
new MartialArtsMaster() {Id = 4, Name = "任我行", Age = 50, Menpai = "明教", Kongfu = "葵花寶典", Level = 1},
new MartialArtsMaster() {Id = 5, Name = "東方不敗", Age = 35, Menpai = "明教", Kongfu = "葵花寶典", Level = 10},
new MartialArtsMaster() {Id = 6, Name = "林平之", Age = 23, Menpai = "華山", Kongfu = "葵花寶典", Level = 7},
new MartialArtsMaster() {Id = 7, Name = "嶽不群", Age = 50, Menpai = "華山", Kongfu = "葵花寶典", Level = 8},
new MartialArtsMaster() {Id = 8, Name = "令狐沖", Age = 23, Menpai = "華山", Kongfu = "獨孤九劍", Level = 10},
new MartialArtsMaster() {Id = 9, Name = "梅超風", Age = 23, Menpai = "桃花島", Kongfu = "九陰真經", Level = 8},
new MartialArtsMaster() {Id = 10, Name = "黃藥師", Age = 23, Menpai = "梅花島", Kongfu = "彈指神通", Level = 10},
new MartialArtsMaster() {Id = 11, Name = "風清揚", Age = 23, Menpai = "華山", Kongfu = "獨孤九劍", Level = 10}
};
//初始化武學
var kongfuList = new List<Kongfu>()
{
new Kongfu() {Id = 1, Name = "打狗棒法", Power = 90},
new Kongfu() {Id = 2, Name = "降龍十八掌", Power = 95},
new Kongfu() {Id = 3, Name = "葵花寶典", Power = 100},
new Kongfu() {Id = 4, Name = "獨孤九劍", Power = 100},
new Kongfu() {Id = 5, Name = "九陰真經", Power = 100},
new Kongfu() {Id = 6, Name = "彈指神通", Power = 100}
};
}
上面定義了兩個類,武林高手和武學,現在我們查詢所有武學級別大於8且門派為丐幫的武林高手。
首先我們使用原始的方法來查詢:
{
var res = new List<MartialArtsMaster>();
foreach (var temp in masterList)
{
if (temp.Level > 8 && temp.Menpai == "丐幫")
{
res.Add(temp);
}
1 使用LINQ查詢,表示式寫法
//1,使用LINQ做查詢( 表示式寫法)
var res = from m in masterList
//from後面設定查詢的集合
where m.Level > 8 && m.Menpai == "丐幫"
//where後面跟上查詢的條件
select m;//表示m的結果結合返回
使用LINQ查詢,擴充套件方法的寫法。其中Where是過濾操作符,根據返回bool值的Func委託引數過濾元素
//過濾方法
static bool Test1(MartialArtsMaster master)
{
if (master.Level > 8) return true;
return false;
}
//2,擴充套件方法的寫法
//var res = masterList.Where(Test1);
var res = masterList.Where(m => m.Level > 8 && m.Menpai == "丐幫");
查詢結果:
LINQ也可以同時查多個表,下面我們取得所學功夫的殺傷力大於90 的武林高手。
2 LINQ 聯合查詢
var res = from m in masterList
from k in kongfuList
where m.Kongfu == k.Name && k.Power > 90
select m;
LINQ 聯合查詢,擴充套件方法用法
var res =
masterList.SelectMany(m => kongfuList, (m, k) => new { master = m, kongfu = k })
.Where(x => x.master.Kongfu == x.kongfu.Name && x.kongfu.Power > 90);
查詢結果:
3 對查詢結果做排序 orderby (descending)
優先等級排序,然後年齡排序
var res = from m in masterList
where m.Level > 8 && m.Menpai == "丐幫"
//orderby m.Age descending // 預設從小到大,加上descending從大到小
orderby m.Level, m.Age //按照多個欄位進行排序,如果欄位的屬性相同,就按照第二個屬性排序
select m;//表示m的結果結合返回
排序擴充套件用法
var res = masterList.Where(m => m.Level > 8 && m.Menpai == "丐幫").OrderBy(m => m.Age);
如果排序判斷條件有多個,後面的排序要用ThenBy
var res = masterList.Where(m => m.Level > 8).OrderBy(m => m.Level).ThenBy(m => m.Age);
查詢結果:
4 Join on集合聯合查詢
var res = from m in masterList
// join...in... 表示要連線的表,on後面為連線條件,等於要用equals,不能用==
join k in kongfuList on m.Kongfu equals k.Name
where k.Power > 90
select new { master = m, kongfu = k };
查詢結果:
5 分組查詢 into groups
把武林高手按照所學功夫分類,看一下那個功夫修煉的人數最多
var res = from k in kongfuList
join m in masterList on k.Name equals m.Kongfu
into groups //分組
orderby groups.Count() // 這個可以獲得數量
select new { kongfu = k, count = groups.Count() };
查詢結果:
6 按照自身欄位分組 group by
var res = from m in masterList
group m by m.Kongfu
into g
select new { count = g.Count(), key = g.Key };//g.Key Key表示是按照那個屬性分的組
結果:
7 量詞操作符 any all 判斷集合中是否滿足某個條件
any判斷集合中是否有一個滿足,all判斷集合中是否全部滿足
bool res = masterList.Any(m => m.Menpai == "長留");
Console.WriteLine(res);
res = masterList.All(m => m.Menpai == "丐幫");
Console.WriteLine(res);
結果: