C#使用LINQ查詢表達(dá)式的基本子句總結(jié)
LINQ查詢表達(dá)式的基本語(yǔ)法很容易掌握,它使用C#常見的語(yǔ)言構(gòu)造,從外觀上看,和我們常用的SQL類似,并且查詢表達(dá)式中的變量可以用匿名類型,所以在很多情況下,不需要指定變量類型就可以構(gòu)建LINQ表達(dá)式。
LINQ的數(shù)據(jù)源可以是數(shù)據(jù)庫(kù)對(duì)象或是XML流等,也可以使實(shí)現(xiàn)了IEnumerable或者泛型IEnumberable<T>接口的集合對(duì)象。
LINQ的基本語(yǔ)法包含如下的8個(gè)上下文關(guān)鍵字,這些關(guān)鍵字和具體的說(shuō)明如下:
| 關(guān)鍵字 | |
| from | 指定范圍變量和數(shù)據(jù)源 |
| where | 根據(jù)bool表達(dá)式從數(shù)據(jù)源中篩選數(shù)據(jù) |
| select | 指定查詢結(jié)果中的元素所具有的類型或表現(xiàn)形式 |
| group | 對(duì)查詢結(jié)果按照鍵值進(jìn)行分組(IGrouping<TKey,TElement>) |
| into | 提供一個(gè)標(biāo)識(shí)符,它可以充當(dāng)對(duì)join、group或select子句結(jié)果的引用 |
| orderby | 對(duì)查詢出的元素進(jìn)行排序(ascending/descending) |
| join | 按照兩個(gè)指定匹配條件來(lái)Equals連接兩個(gè)數(shù)據(jù)源 |
| let | 產(chǎn)生一個(gè)用于存儲(chǔ)查詢表達(dá)式中的子表達(dá)式查詢結(jié)果的范圍變量 |
下面依此總結(jié)這8個(gè)關(guān)鍵字的常用查詢語(yǔ)句寫法。
1.from子句
如果要寫一個(gè)LINQ表達(dá)式,就必須是以from子句開頭。個(gè)人覺得from子句中需要注意的地方就是多個(gè)from子句的書寫。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace LINQ
{
/// <summary>
/// LINQ,重點(diǎn)是感悟from子句中的查詢變量的靈活
/// </summary>
class Program
{
static void Main(string[] args)
{
//1單個(gè)form子句
string[] values = { "LINQ學(xué)習(xí)","LINQ基本語(yǔ)句","from子句","單個(gè)from子句"};
var value = from v in values
where v.IndexOf("LINQ") > -1
select new { v, v.Length };
foreach (var n in value)
{
Console.WriteLine("{0},{1}",n.v,n.Length );
}
Console.ReadKey(false);
//2使用LINQ查詢ArrayList
ArrayList gList = new ArrayList();
gList.Add(new GustInfo { Name="DebugLZQ", Age=26, Tel="88888888"});
gList.Add(new GustInfo { Name="博客園",Age=6, Tel ="666666"});
gList.Add(new GustInfo { Name = "M&MSoft", Age =9, Tel = "55555" });
var query = from GustInfo gust in gList
where gust.Age > 9
select gust;//范圍變量gust制定了數(shù)據(jù)類型
foreach (GustInfo g in query)
{
Console.WriteLine("{0} 年齡:{1} 電話:{2}",g.Name,g.Age,g.Tel );
}
Console.ReadKey(false);
//3復(fù)合from子句
List<GustInfo2> gList2 = new List<GustInfo2>()
{
new GustInfo2{ Name="DebugLZQ",Age=26,TelTable=new List<string>(){"8888888","138******"}},
new GustInfo2{ Name="博客園",Age=6,TelTable =new List<string>(){"666666","138******"}},
new GustInfo2{ Name="M&MSoft",Age=9,TelTable=new List<string>(){"55555","138******"}}
};
//gust、tel都是查詢變量,作用域?yàn)楫?dāng)前查詢語(yǔ)句?。。?
var query2 = from gust in gList2
from tel in gust.TelTable
where tel.IndexOf("5555") > -1
select gust;
foreach (var g in query2)
{
Console.WriteLine("{0} 年齡{1}",g.Name,g.Age );
foreach (var t in g.TelTable)
{
Console.WriteLine("電話:{0}",t);
}
}
Console.ReadKey(false);
//4多個(gè)from子句
var query3 = from GustInfo gust in gList
where gust.Age > 6
from GustInfo2 gust2 in gList2
where gust2.Age> 9
select new { gust, gust2 };//查詢結(jié)果定制
foreach (var g in query3)
{
Console.WriteLine("{0} {1}", g.gust.Name, g.gust2.Name);
}
Console.ReadKey(false);
}
}
}
程序的運(yùn)行結(jié)果如下:
程序中列舉了from子句的用法示例,注意復(fù)合from子句和多個(gè)from子句的書寫,同時(shí)需要理解范圍變量和數(shù)據(jù)源變量這兩個(gè)概念。
2.where子句
where子句,它是LINQ表達(dá)式的元素篩選機(jī)制,除了開始和結(jié)束的位置,它幾乎可以出現(xiàn)在LINQ表達(dá)式的任意位置上。
在一個(gè)LINQ表達(dá)式中,可以有where子句,也可以沒有;可以有一個(gè),也可以有多個(gè);多個(gè)where子句之間的邏輯關(guān)系相當(dāng)于邏輯“與”,每個(gè)where子句可以包含1個(gè)或多個(gè)bool邏輯表達(dá)式,這些條件成為謂詞,謂詞邏輯之間用的是“&&”“||”等而不是SQL中的and 、or。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQ_WHERE
{
/// <summary>
/// LINQ where子句
/// </summary>
class Program
{
static void Main(string[] args)
{
//1常見的where語(yǔ)句
List<GustInfo> gList = new List<GustInfo>()
{
new GustInfo(){ Name="DebugLZQ", Age=26,Tel="88888888"},
new GustInfo(){ Name="cnblogs",Age=6,Tel="666666"},
new GustInfo(){ Name="M&MSoft",Age=9,Tel="55555"}
};
var query = from gust in gList
where (gust.Name.Length > 7 || gust.Name.Substring(0, 1) == "M") && gust.Age > 9
select new { gust.Name, gust.Age };
foreach (var g in query)
{
Console.WriteLine("{0},{1}", g.Name, g.Age);
}
Console.ReadKey(false);
//2.在where子句中使用自定義函數(shù)
var query2 = from GustInfo gust in gList
where gust.Name.Length > 5
&& Check(gust.Name)
select gust;
foreach (var g in query2)
{
Console.WriteLine("{0},{1},{2}", g.Name, g.Age, g.Tel);
}
Console.ReadKey(false);
//3.動(dòng)態(tài)謂詞的篩選
//定義動(dòng)態(tài)謂詞數(shù)組,在實(shí)際開發(fā)中可以動(dòng)態(tài)獲得
string[] names = { "SB","XXX","***","@@@","一些敏感詞"};
var query3 = from GustInfo guest in gList
where !names.Contains(guest.Name)
select guest;
foreach (var q in query3)
{
Console.WriteLine("{0} 年齡:{1},電話:{2}",q.Name,q.Age,q.Tel );
}
Console.ReadKey(false);
}
//自定義函數(shù)
static bool Check(string name)
{
if (name.Substring(0, 1) == "N")
return false;
return true;
}
}
}
需要注意一些常用的where子句的寫法。程序的運(yùn)行結(jié)果如下:
3.Select子句
在select子句上可以非常靈活的處理查詢到的元素,然后再把結(jié)果返回。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQ_select
{
/// <summary>
/// LINQ select
/// 在select子句上,可以非常靈活的處理查詢到的元素,然后再把結(jié)果返回
/// </summary>
class MyGustInfo
{
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<GustInfo> gList = new List<GustInfo>()
{
new GustInfo(){ Name="DebugLZQ", Age=25, Tel="88888888"},
new GustInfo(){ Name="cnblogs", Age=6, Tel="666666"},
new GustInfo(){ Name="M&M", Age=9, Tel="55555"}
};
var query = from gust in gList
where gust.Age >= 9 && gust.Age <= 30
select gust.Name.Replace("&", "mm");//select子句靈活應(yīng)用
var query2 = from gust in gList
where gust.Age >= 9 && gust.Age <= 30
select MyProc(gust.Name);
var query3 = from gust in gList
where gust.Age >= 9 && gust.Age <= 30
select new { gust.Name,gust.Age};
var query4 = from gust in gList
where gust.Age >= 9 && gust.Age <= 30
select new MyGustInfo { Name=gust.Name+"My", Age=gust.Age+1};//對(duì)查詢結(jié)果進(jìn)行投影
foreach (var v in query)
{
Console.WriteLine(v);
}
foreach (var v in query2)
{
Console.WriteLine(v);
}
foreach (var v in query3)
{
Console.WriteLine(v.Name+v.Age );
}
foreach (var v in query4)
{
Console.WriteLine(v.Name+v.Age );
}
Console.ReadKey(false);
}
static string MyProc(string s)
{
return s + "Better";
}
}
}
程序的運(yùn)行結(jié)果如下:
4.group子句
根據(jù)語(yǔ)法的規(guī)定,LINQ表達(dá)式必須以from子句開頭,以select或group子句結(jié)束,所以除了使用select來(lái)返回結(jié)果外,也可以使用group子句來(lái)返回元素分組后的結(jié)果。
group子句返回的是一個(gè)基于IGrouping<TKey,TElement>泛型接口的對(duì)象序列。
語(yǔ)法和SQL的group有點(diǎn)區(qū)別,不注意的話可能會(huì)寫錯(cuò)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQ_group
{
/// <summary>
/// LINQ group子句
/// </summary>
class Program
{
static void Main(string[] args)
{
List<GustInfo> gList = new List<GustInfo>()
{
new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"},
new GustInfo(){ Name="Sarah",Age=25,Tel="159********"},
new GustInfo(){ Name="Jerry",Age=35,Tel="135********"},
new GustInfo(){ Name="M&M",Age=16,Tel="136********"},
new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"},
new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"},
};
var query = from guest in gList
group guest by guest.Name.Substring(0, 1);//分組鍵key是string類型
//遍歷鍵值和鍵值所屬元素
foreach (IGrouping<string, GustInfo> guestGroup in query)
{
Console.WriteLine("分組鍵:{0}",guestGroup.Key );
foreach (var g in guestGroup)
{
Console.WriteLine("{0} 年齡:{1} 電話:{2}",g.Name,g.Age,g.Tel );
}
}
Console.ReadKey(false);
Console.WriteLine("-----------------------------------");
var query2 = from guest in gList
group guest by guest.Age > 20;//分組鍵key是bool類型表達(dá)式的結(jié)果
foreach (IGrouping<bool, GustInfo> guestGroup in query2)
{
Console.WriteLine("年齡是否大于20 分組鍵:{0}", guestGroup.Key);
foreach (var g in guestGroup)
{
Console.WriteLine("{0} 年齡:{1} 電話:{2}", g.Name, g.Age, g.Tel);
}
}
Console.ReadKey(false);
}
}
}
程序的運(yùn)行結(jié)果如下:
5.into子句
into子句作為一個(gè)臨時(shí)標(biāo)識(shí)符,用于group、select、join子句中充當(dāng)其結(jié)果的引用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQ_into
{
/// <summary>
/// LINQ group
/// </summary>
class Program
{
static void Main(string[] args)
{
List<GustInfo> gList = new List<GustInfo>()
{
new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"},
new GustInfo(){ Name="Sarah",Age=25,Tel="159********"},
new GustInfo(){ Name="Jerry",Age=35,Tel="135********"},
new GustInfo(){ Name="M&M",Age=16,Tel="136********"},
new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"},
new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"},
};
//1.into用于group子句
var query = from guest in gList
group guest by guest.Name.Substring(0, 1) into grguest
orderby grguest.Key descending
select grguest;
var query2 = from guest in gList
group guest by guest.Name.Substring(0, 1) into grguest
orderby grguest.Key ascending
select grguest;
//2.select 子句中的into子句
var query3 = from guest in gList
select new { NewName = guest.Name, NewAge = guest.Age } into newguest
orderby newguest.NewAge
select newguest;
foreach (var guestGroup in query)
{
Console.WriteLine("分組鍵:{0}",guestGroup.Key );
foreach (var g in guestGroup)
{
Console.WriteLine("{0} 電話:{1}",g.Name,g.Tel );
}
}
Console.ReadKey(false);
foreach (var newg in query3)
{
Console.WriteLine("{0} 年齡:{1}",newg.NewName,newg.NewAge );
}
Console.ReadKey(false);
}
}
}
程序運(yùn)行結(jié)果如下:
6.orderby子句、thenby子句
LINQ可以按照元素的一個(gè)或多個(gè)屬性對(duì)元素進(jìn)行排序。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQ_orderby
{
class Program
{
/// <summary>
/// LINQ orderby (ascending descending)
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
List<GustInfo> gList = new List<GustInfo>()
{
new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"},
new GustInfo(){ Name="Sarah",Age=25,Tel="159********"},
new GustInfo(){ Name="Jerry",Age=35,Tel="135********"},
new GustInfo(){ Name="M&M",Age=16,Tel="136********"},
new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"},
new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"},
};
//按照年齡排序
var query = from guest in gList
orderby guest.Age
select guest;
var query1 = from guest in gList
orderby guest.Age ascending
select guest;
var query2 = from guest in gList
orderby guest.Age descending
select guest;
//按照年齡進(jìn)行排序,按照名字字?jǐn)?shù)進(jìn)行次要排序
var query3 = from guest in gList
orderby guest.Age, guest.Name.Length
select guest;
var query4 = from guest in gList
orderby guest.Age descending , guest.Name.Length ascending
select guest;
var query5 = from guest in gList
orderby guest.Age, guest.Name.Length,guest.Tel
select guest;
foreach (var guest in query2)
{
Console.WriteLine("{0} 年齡:{1} 電話:{2}",guest.Name,guest.Age,guest.Tel );
}
Console.ReadKey(false);
foreach (var guest in query4)
{
Console.WriteLine("{0} 年齡:{1} 電話:{2}", guest.Name, guest.Age, guest.Tel);
}
Console.ReadKey(false);
}
}
}
程序運(yùn)行結(jié)果如下:
7.let子句
let子句用于在LINQ表達(dá)式中存儲(chǔ)子表達(dá)式的計(jì)算結(jié)果。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQ_let
{
/// <summary>
/// LINQ let用來(lái)存子儲(chǔ)表達(dá)式的計(jì)算結(jié)果
/// </summary>
class Program
{
static void Main(string[] args)
{
List<GustInfo> gList = new List<GustInfo>()
{
new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"},
new GustInfo(){ Name="Sarah",Age=25,Tel="159********"},
new GustInfo(){ Name="Jerry",Age=35,Tel="135********"},
new GustInfo(){ Name="M&M",Age=16,Tel="136********"},
new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"},
new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"},
};
//使用let子句創(chuàng)建范圍變量g,并通過(guò)g構(gòu)建查詢表達(dá)式
var query = from guest in gList
let g = guest.Name.Substring(0, 1)
where g == "D" || g == "J"
select guest;
//也可以不使用let,上面的語(yǔ)句等效于下
var query2 = from guest in gList
where guest.Name.Substring(0, 1) == "D" || guest.Name.Substring(0, 1) == "J"
select guest;
foreach (var g in query)
{
Console.WriteLine("{0} 年齡:{1} 電話:{2}",g.Name,g.Age,g.Tel );
}
Console.ReadKey(false);
Console.WriteLine("不使用let,等效的語(yǔ)句結(jié)果");
foreach (var g in query2)
{
Console.WriteLine("{0} 年齡:{1} 電話:{2}", g.Name, g.Age, g.Tel);
}
Console.ReadKey(false);
}
}
}
程序的運(yùn)行結(jié)果如下:
8.join子句
如果一個(gè)數(shù)據(jù)源中元素的某個(gè)屬性可以跟另外一個(gè)數(shù)據(jù)源的中元素的某個(gè)屬性進(jìn)行相等比較,那么這兩個(gè)數(shù)據(jù)源可以用join子句進(jìn)行關(guān)聯(lián)。
join子句使用equals關(guān)鍵字進(jìn)行相等比較,而不是常用的雙等號(hào)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQ_join
{
class Program
{
static void Main(string[] args)
{
//定義兩個(gè)數(shù)據(jù)源
List<GustInfo> gList = new List<GustInfo>()
{
new GustInfo(){ Name="DebugLZQ",Age=26,Tel="187********"},
new GustInfo(){ Name="Sarah",Age=25,Tel="159********"},
new GustInfo(){ Name="Jerry",Age=35,Tel="135********"},
new GustInfo(){ Name="M&M",Age=16,Tel="136********"},
new GustInfo(){ Name="DebugMan",Age=26,Tel="136********"},
new GustInfo(){ Name="Jerry&Tom",Age=19,Tel="136********"},
};
List<GuestTitle> titleList = new List<GuestTitle>()
{
new GuestTitle(){Name="DebugLZQ",Title="Soft Engineer"},
new GuestTitle(){Name="DebugLZQ",Title="Team Leader"},
new GuestTitle(){Name="Sarah",Title="Test Engineer"},
new GuestTitle(){Name="Jerry",Title="Head Master"}
};
//1.根據(jù)姓名進(jìn)行內(nèi)連接
var query = from guest in gList
join title in titleList on guest.Name equals title.Name
select new { Name=guest.Name ,Title=title.Title,Age=guest.Age };
foreach (var g in query)
{
Console.WriteLine("{0} {1} 年齡:{2}",g.Name,g.Title ,g.Age );
}
Console.ReadKey(false);
//前面的多個(gè)from實(shí)現(xiàn)相同的作用:與內(nèi)連接區(qū)別在于:這個(gè)中間的操作是叉乘獲得笛卡爾積
var query2=from guest in gList
from title in titleList
where guest.Name==title.Name
select new { Name = guest.Name, Title = title.Title, Age = guest.Age };
foreach (var g in query2)
{
Console.WriteLine("{0} {1} 年齡:{2}", g.Name, g.Title, g.Age);
}
Console.ReadKey(false);
//2.根據(jù)姓名進(jìn)行分組連接
//根據(jù)名字分組后,得到每個(gè)名字下的全部名稱
var query3 = from guest in gList
join title in titleList on guest.Name equals title.Name into tgroup
select new { Name=guest.Name,Titles=tgroup };
foreach (var g in query3)
{
Console.WriteLine(g.Name);
foreach (var g2 in g.Titles)
{
Console.WriteLine(" {0}",g2.Title );
}
}
Console.ReadKey(false);
//3.根據(jù)姓名進(jìn)行左外連接
//無(wú)職務(wù)的輸出為空缺
var query4 = from guest in gList
join title in titleList on guest.Name equals title.Name into tgroup
from subtitle in tgroup.DefaultIfEmpty()
select new { Name=guest.Name,Title=subtitle==null?"空缺":subtitle.Title };
foreach (var g in query4)
{
Console.WriteLine("{0} {1} ",g.Name ,g.Title );
}
Console.ReadKey(false);
}
}
}
程序結(jié)果如下:
以上就是LINQ的基本子句的常用用法,文字不是很多,因?yàn)榇a中都有詳細(xì)的注釋說(shuō)明。
上一篇:C#隱式/顯示實(shí)現(xiàn)接口方法詳解
欄 目:C#教程
下一篇:C#中的委托數(shù)據(jù)類型簡(jiǎn)介
本文標(biāo)題:C#使用LINQ查詢表達(dá)式的基本子句總結(jié)
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/6638.html
您可能感興趣的文章
- 01-10C#使用Dispose模式實(shí)現(xiàn)手動(dòng)對(duì)資源的釋放
- 01-10C#3.0使用EventLog類寫Windows事件日志的方法
- 01-10C#使用windows服務(wù)開啟應(yīng)用程序的方法
- 01-10c# ArrayList的使用方法小總結(jié)
- 01-10C#使用ADO.Net部件來(lái)訪問(wèn)Access數(shù)據(jù)庫(kù)的方法
- 01-10C#使用Mutex簡(jiǎn)單實(shí)現(xiàn)程序單實(shí)例運(yùn)行的方法
- 01-10使用Nopcommerce為商城添加滿XX減XX優(yōu)惠券功能
- 01-10C#中yield用法使用說(shuō)明
- 01-10C#編程和Visual Studio使用技巧(下)
- 01-10C#編程和Visual Studio使用技巧(上)


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載


