LINQ語法詳解


public class Person
    {
        public string Name
        {
            get;
            set;
        }
        public string Sex
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
    }
List list = new List()
 {
    new Person(){ Name="Olive",Sex="",Age=22},
    new Person(){ Name="Moyao",Sex="",Age=23},
    new Person(){ Name="Momo",Sex="",Age=22},
    new Person(){ Name="Only",Sex="",Age=20},
    new Person(){ Name="Love",Sex="",Age=21},
    new Person(){ Name="For",Sex="",Age=22},
    new Person(){ Name="Remote",Sex="",Age=23},
    new Person(){ Name="Snow",Sex="",Age=23}
 };
//從list集合中選出性別為“女”的人
    var girls = from g in list
                where g.Sex == ""
                select g;
    //從list集合中選出性別為“男”的人
    var boys = list.Where(p => p.Sex == "");

    Console.WriteLine("girl" + System.Environment.NewLine);
    foreach (var g in girls)
    {
        Console.WriteLine("姓名:" + g.Name + "--性別:" + g.Sex + "--年齡:" + g.Age);
        Console.WriteLine(System.Environment.NewLine);

    }


    context.Response.Write("boy" + System.Environment.NewLine);
    foreach (var b in boys)
    {
        Console.WriteLine("姓名:" + b.Name + "--性別:" + b.Sex + "--年齡:" + b.Age);
        Console.WriteLine(System.Environment.NewLine);
    }

輸出結果如下:

細心的朋友們可能會發現從list集合中獲取信息的方式不一樣,在獲取性別為“女”的集合中采用的是from g in list where g.Sex== "女" select g;

而在獲取性別為“男”的集合中采用的為list.Where(p => p.Sex == "男");

或許會有人問,這兩種查詢方式有什么區別呢?上面的第一種方法叫查詢語法(query syntax),看上去和SQL的語句很相似。查詢語法使用查詢表達式書寫。第二種方法叫方法語法(method syntax)是命令形式,它使用的是標准的方法調用,方法是一組叫做標准查詢運算符的方法。雖然形式上這兩種查詢方法不同,事實上這兩種方法存在着緊密的聯系,在CLR內只識別查詢方法,因此在每次查詢的時候編譯器在編譯時會將查詢語句翻譯為查詢方法,當然大部分的查詢方法也都有對應的查詢語句形式,例如:where對應Where(),select對應Select(),orderby對應orderby(),group對應group(),join對應Join(),distinct對應Distinct(),union對應Union(),Intersect對應Intersect(),except對應Except(),等等。

我們看SQL查詢形式:select查詢內容 from數據源 where查詢條件,也就是分為數據源、查詢條件、查詢內容這三部分,在LINQ查詢里也是分這三部分,從上面的例子中我們可以知道它的查詢方式是這樣的from a(查詢內容) in數據源 where查詢條件 select a(查詢內容)

下邊就從最基本的介紹開始。

1、from

在SQL里邊from后跟的是數據源,當然在LINQ里from子句指定的也是要作為數據源使用的數據集合,但是它引入了迭代變量,迭代變量有序表示數據源的每一個元素,最后查詢返回的是一個迭代變變量的集合。

2、Where/where()

在SQL里where后跟的是查詢條件,在LINQ里也是一樣的。

請看示例:

//查詢年齡大於21且性別為女的人員的個人信息
var girls1 = from g in list
where g.Age > 21 && g.Sex == ""
select g;

//使用查詢方法查詢
var girls1 = list.Where(g => g.Age > 21 && g.Sex == "");
Console.WriteLine("年齡大於21且性別為女的個人信息:");

foreach (var g in girls1)
{
  Console.WriteLine("姓名:" + g.Name + "--性別:" + g.Sex + "--年齡:" + g.Age);
}

實驗結果:

從實驗結果中我們可以看到,在查詢語句中where后邊也可以跟一個或多個查詢條件,去篩選數據,以得到想要的結果,或許還有人對使用查詢方法有點疑問,查詢方法where()里邊的參數到底是什么呢?這里就用到了上一節我們講的Lambda表達式。

請看Where()的原型:

where()語法是:

public static IEnumerable where(
this IEnumerable source,
Func<TSource,bool> predicate)

由上一節學的知識我們可以知道該方法是一個泛型的擴展方法,該方法只接受一個Func<TSource,bool>泛型委托參數,這里的predicate是一個判斷條件。

我們上邊用的list.Where(g=>g.Age>21 && g.Sex) 高亮部分就相當於一個委托參數,所以用where()查詢方法才能查出符合條件的信息。至於上邊提到的Selec()、Orderby()等查詢方法語法原型都是泛型的擴展方法和where()差不多,后邊就不再過多的介紹其方法原型了。

3、select/select()

select篩選出符合條件的數據

用查詢語句查詢var g1=from g in list where g.Name="Olive" select g1;

用查詢方法查詢姓名為Olive的人員信息:

var g1 = list.Select(p=>p).Where(p=>p.Name == "Olive");

 結果如下:

4、排序:orderby/OrderBy()、thenBy()、ThenByDescending()

//用orderby進行排序(默認升序)
Var ps=from p in list select p orderby

//用OrderBy()進行排序(升序)
var g11 = list.OrderBy(p => p.Age);

結果如圖:

//用orderby descending降序排列
var ps=from p in list select p orderby p.Age descending

//用OrderByDescending()降序排序
var g11 = list.OrderByDescending(p => p.Age);

結果如圖:

 

用ThenBy()做二次排序,先按年齡的升序排序,如果年齡相等的就再按姓名升序排序

var g12 = list.OrderBy(p => p.Age).ThenBy(p => p.Name);

結果如圖:

//用group子句進行分組
Var ps=from p in list group p.Sex into p select p;

//使用GroupBy()進行分組
var g11 = list.OrderByDescending(p => p.Age).GroupBy(p=>p.Sex);

 

用ThenByDescending()做二次排序,先按年齡的升序排序,如果年齡相等的就再按姓名降序排序 

var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name);

結果如圖:

 

5、group/GroupBy()

使用group子句可產生按照指定的鍵組織的組序列。

//用group子句進行分組
Var ps=from p in list group p.Sex into p select p;

//使用GroupBy()進行分組
var g11 = list.OrderByDescending(p => p.Age).GroupBy(p=>p.Sex);

結果如下:

6、Take、TakeWhile、Skip、SkipWhile

6.1、Take:用於從輸入序列中返回指定數量的元素

//從滿足條件的的序列中返回3條信息

var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Take(3);

6.2、TakeWhile:只要滿足一定條件的就會馬上返回序列元素

var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).TakeWhile(p=>p.Sex=="");

結果如圖:

6.3 、Skip:用於從輸入序列中跳過指定個數的元素,返回由序列中剩余的元素所組成的新序列

/跳過4個指定元素,然后將剩余的元素組成新序列返回
var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Skip(4);

6.4、SkipWhile:用於從輸入序列中跳過滿足一定條件指定數量的元素,返回由序列中剩余的元素所組成的新序列

//跳過姓名為“Olive”的信息,然后將剩余的的元素組成新的序列返回

var g12 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).SkipWhile(p=>p.Name=="Olive");

結果如下:

7、Count(),Max()/Min(),Average(),Sum()聚合方法

7.1、Count():統計序列中元素個數

示例:

//求最大年齡:
var g121 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Max(p => p.Age);
Console.WriteLine("最大年齡為:"+g121);

結果:

示例:

//求最小年齡:
var g121 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Min(p => p.Age);
Console.WriteLine("最小年齡為:"+g121);

結果:

7.3、Average()求平均值

示例:

//求平均年齡:
var g121 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Average(p => p.Age);
Console.WriteLine("平均年齡為:"+g121);

結果:

7.4、Sum()累加求和

示例:

//累加年齡:
var g121 = list.OrderBy(p => p.Age).ThenByDescending(p => p.Name).Average(p => p.Age);
Console.WriteLine("累加年齡為:"+g121);

結果:

8、Join(),GroupJoin(),Union(),Intersect(),Except(),Contact(),Distinct操作符

8.1、Join()用於連接兩個序列,和SQL里的Join語句連接多表一樣,連接操作接受兩個集合然后創建一個臨時的對象集合,每個對象包含原始集合對象中的所有字段,使用連接來結合兩個或更多個集合中的數據。

例如:

//這里使用上邊新建的Person類,然后在新建一個Profession(職業)類
Public class Profession
{
    Public string Name{get;set:}
    Public string Zhiye{get;set;}
}

List<Person> list=new List<Person>()
{
    new Person(){ Name="Olive",Sex="",Age=22},
    new Person(){ Name="Moyao",Sex="",Age=23},
    new Person(){ Name="Momo",Sex="",Age=22},
    new Person(){ Name="Only",Sex="",Age=20},
    new Person(){ Name="Love",Sex="",Age=21},
    new Person(){ Name="For",Sex="",Age=22},
    new Person(){ Name="Remote",Sex="",Age=23},
    new Person(){ Name="Snow",Sex="",Age=23}
};

List<Profession> listprofession = new List<Profession>
{
    new Profession() { Name = "Olive", ZhiYe = "會計" },
    new Profession() { Name = "Remote", ZhiYe = "IT Coder" },
    new Profession() { Name = "BLove", ZhiYe = "學生" },
    new Profession(){ Name="AFor",ZhiYe="作家"}
};

//使用Join查詢語句查詢,從Person序列和Profession序列里查詢出姓名相同的信息,組合成一個新的序列,並顯示姓名和職業
var showzhiye = from p in list
join pf in listprofession on p.Name equals pf.Name
select new
{
    Name = p.Name,
    ZhiYe = pf.ZhiYe
};

foreach (var p in showzhiye)
{
    Console.WriteLine("姓名:" + p.Name + "職業:" + p.ZhiYe);
}

//使用Json()方法查詢:
var showzhiye = list.Join(listprofession, p => p.Name, pf => pf.Name, (p, pf) => new
{
    Name = p.Name,
    ZhiYe = pf.ZhiYe
});

兩種方法查詢的結果一樣如下:


8.2、GroupJoin():將基於鍵相等對兩個序列的元素進行關聯並對結果進行分組。使用默認的相等比較器對鍵進行比較。

var showzhiye = list.GroupJoin(listprofession, p => p.Name, pf => pf.Name, (p, pf) => new{ Name = p.Name, ZhiYe = pf.Max(pf1=>pf1.Name)});

var showzhiye = listprofession.GroupJoin(list, pf => pf.Name, p => p.Name, (pf, p) => new
{
    Name = pf.Name,
    ZhiYe =pf.ZhiYe,
    Count=p.Count()
});

結果:

8.3、Union():用於將兩個輸入序列中的元素合並成一個新的序列,且新序列中自動去除重復的序列

示例:

List<Person> list1 = new List<Person>()
{
    new Person(){ Name="Olive",Sex="",Age=18},
    new Person(){ Name="Moyao",Sex="",Age=19},
    new Person(){ Name="Momo",Sex="",Age=20},
    new Person(){ Name="Olive116",Sex="",Age=18},
    new Person(){ Name="Moyao116",Sex="",Age=19},
    new Person(){ Name="Momo116",Sex="",Age=20},
};

var uniontest = list.Union(list1);//將list1和上邊所示的list合並,自動去除重復列

foreach (var p in uniontest)
{
    Console.WriteLine("姓名:" + p.Name + "年齡:"+p.Age +"性別:"+p.Sex );
}

結果:

8.4、Intersect():求兩個序列的交集,將兩個序列中相同的元素挑選出來組成一個新的序列

這里還是用8.3里的數據源list1、list

示例:

var intersectTest = list1.Intersect(list);
foreach (var p in intersectTest)
{
    Console.WriteLine("姓名:" + p.Name + "年齡:"+p.Age +"性別:"+p.Sex );

}

結果:

8.5、Except(),現有A、B兩序列,返回僅在A序列中的元素所組成的序列,相當於求差集

var ExceptTest = list.Except(list1);

8.6、Contact():聯接兩個序列

示例:

var ExceptTest = list.Concat(list1);
foreach (var p in ExceptTest)
{
    Console.WriteLine("姓名:" + p.Name + "年齡:"+p.Age +"性別:"+p.Sex );
}

結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM