1、语法
1、LINQ所处在的主要命名空间:System.Linq
2、LINQ处理的核心对象就是IEnumerable可枚举对象,包括泛型枚举。换句话说当你要处理的对象为IEnumerable类型对象时,即可使用LINQ。
在没有经过其它处理的情况下将返回一个新的IEnumerable序列,另外LING含有“延迟加载”特性。
3、关键字(摘自MSDN)
from: 指定数据源和范围变量(类似于迭代变量)
where: 根据一个或多个由逻辑“与”和逻辑“或”运算符(&&或||)分隔的布尔表达式筛选源元素
select:指定当执行查询时返回的序列中的元素将具有的类型和形式
group:按照指定的键值对查询结果进行分组
into:提供一个标识符,它可以充当对 join、group、select子句的结果的引用
orderby:基于元素类型的默认比较器按升序或降序对查询结果进行排序
join:基于两个指定匹配条件之间的相等比较来关联两个数据源
let:引入一个用于存储查询表达式中的子表达式结果的范围变量
in:join 子句中的上下文关键字
on:join 子句中的上下文关键字
equals:join 子句中的上下文关键字
by:group 子句中的上下文关键字
ascending:orderby 子句中的上下文关键字
descending:orderby 子句中的上下文关键字
4、语法说明
每个LINQ语句都以from作为开头,以select作为结束,这点和T-SQL语法不一致。
样例:IEnumerable<T> nums = from n in nums where ... orderby ... select ...
2、案例
{
string[] words = { " hello ", " wonderful ", " linq ", " beautiful ", " world " };
// 查询出较短的单词
var shortsWords = from word in words
where word.Length <= 5
select word;
// 结果:hello ling world
foreach ( var word in shortsWords)
{
Console.WriteLine(word);
}
Console.ReadKey();
{
string[] words = { " hello ", " wonderful ", " linq ", " beautiful ", " world " };
// 按长度将单词分组
var groups = from word in words
group word by word.Length into lengthGroups
orderby lengthGroups.Key descending
select new { Length = lengthGroups.Key,Words=lengthGroups };
foreach ( var group in groups)
{
Console.WriteLine( " 单词长度为:{0} ",group.Length);
foreach ( string word in group.Words)
{
Console.WriteLine( " " + word);
}
}
Console.ReadKey();
{
List<Class> clist = new List<Class> {
new Class{ CId= " C1 ",CName= " Java " },
new Class{ CId= " C2 ",CName= " .NET " },
new Class{ CId= " C3 ",CName= " Test " }
};
List<Student> slist = new List<Student> {
new Student{ SId= " S001 ",SName= " 彭飞 ",SAge= 27,CId= " C2 " },
new Student{ SId= " S002 ",SName= " 张三 ",SAge= 20,CId= " C2 " },
new Student{ SId= " S003 ",SName= " 李四 ",SAge= 25,CId= " C1 " },
new Student{ SId= " S003 ",SName= " 王五 ",SAge= 25,CId= " C4 " }
};
// 内联查询
var query_1 = from s in slist
join c in clist on s.CId equals c.CId
select new { SId = s.SId, SName = s.SName, CName=c.CName };
foreach ( var q in query_1)
{
Console.WriteLine( " {0}\t{1}\t{2} ",q.SId,q.SName,q.CName);
}
Console.WriteLine( " ---------------------------- ");
// 左外联查询
var query_2 = from s in slist
join c in clist on s.CId equals c.CId into g
from subpet in g.DefaultIfEmpty()
select new { SId = s.SId, SName = s.SName, CName= (subpet == null ? null : subpet.CName) };
foreach ( var q in query_2)
{
Console.WriteLine( " {0}\t{1}\t{2} ", q.SId, q.SName, q.CName);
}
Console.ReadKey();
{
Book[] books = new Book[] {
new Book( " Java ", " 张三 ", 2012),
new Book( " .NET ", " 李四 ", 2012),
new Book( " Test ", " 王五 ", 2000)
};
XElement xml = new XElement( " books ",
from book in books
where book.Year == 2012
select new XElement( " book ",
new XAttribute( " title ", book.Title),
new XElement( " publisher ", book.Publisher)
)
);
Console.WriteLine(xml);
Console.ReadKey();
3、Lambda 表达式
入门示例:
{
var processes = Process.GetProcesses()
.Where(process => process.WorkingSet64 > 20* 1024* 1024)
.OrderByDescending(process => process.WorkingSet64)
.Select(process => new { process.Id, Name=process.ProcessName });
foreach( var p in processes)
{
Console.WriteLine(p.Name);
}
Console.ReadKey();
{
var processes = from process in Process.GetProcesses()
where process.WorkingSet64 > 20 * 1024 * 1024
orderby process.WorkingSet64 descending
select new { process.Id, Name = process.ProcessName };
foreach( var p in processes)
{
Console.WriteLine(p.Name);
}
Console.ReadKey();
Func<T,TResult> 泛型委托类型:
{
Func< int, bool> isOdd = i => (i & 1) == 1;
for ( int i = 0; i < 10; i++)
{
if (isOdd(i))
{
Console.WriteLine( " {0} is odd ", i);
}
else
{
Console.WriteLine( " {0} is even ", i);
}
}
Console.ReadKey();
示例:
{
List<Student> slist = new List<Student> {
new Student{ SId= " S001 ",SName= " 彭飞 ",SAge= 27,CId= " C2 " },
new Student{ SId= " S002 ",SName= " 张三 ",SAge= 20,CId= " C2 " },
new Student{ SId= " S003 ",SName= " 李四 ",SAge= 25,CId= " C1 " },
new Student{ SId= " S003 ",SName= " 王五 ",SAge= 25,CId= " C4 " }
};
var stus = slist.Where(stu => stu.SName.Contains( " 飞 "))
.Select(stu => stu.SName);
foreach ( var s in stus)
{
Console.WriteLine(s);
}
Console.ReadKey();
标准查询操作符:(以下为常用的)
过滤:Where
投影:Select、SelectMany
分区:Skip、Take
连接:GroupJoin、Join
排序:OrderBy、OrderByDescending、ThenBy、ThenByDescending
分组:GroupBy
集合:Distinct
转换:ToArray、ToDictionary、ToList
生成:DefaultIfEmpty
聚集:Count、Max、Min、Sum
1、约束操作符 Where
{
List<Student> slist = new List<Student> {
new Student{ SId= " S001 ",SName= " 彭飞 ",SAge= 27,CId= " C2 " },
new Student{ SId= " S002 ",SName= " 张三 ",SAge= 20,CId= " C2 " },
new Student{ SId= " S003 ",SName= " 李四 ",SAge= 25,CId= " C1 " },
new Student{ SId= " S003 ",SName= " 王五 ",SAge= 25,CId= " C4 " }
};
// 约束操作符 Where
var stus = slist.Where(stu => stu.SName.Contains( " 飞 "));
// 等价于
var query = from stu in slist
where stu.SName.Contains( " 飞 ")
select stu;
2、投影操作符 Select
{
List<Student> slist = new List<Student> {
new Student{ SId= " S001 ",SName= " 彭飞 ",SAge= 27,CId= " C2 " },
new Student{ SId= " S002 ",SName= " 张三 ",SAge= 20,CId= " C2 " },
new Student{ SId= " S003 ",SName= " 李四 ",SAge= 25,CId= " C1 " },
new Student{ SId= " S003 ",SName= " 王五 ",SAge= 25,CId= " C4 " }
};
// 投影操作符 Select
var stus = slist.Select(stu => stu.SName);
// 等价于
var query = from stu in slist
select stu.SName;
3、操作符 Distinct
{
List<Student> slist = new List<Student> {
new Student{ SId= " S001 ",SName= " 彭飞 ",SAge= 27,CId= " C2 " },
new Student{ SId= " S002 ",SName= " 张三 ",SAge= 20,CId= " C2 " },
new Student{ SId= " S003 ",SName= " 李四 ",SAge= 25,CId= " C1 " },
new Student{ SId= " S003 ",SName= " 王五 ",SAge= 25,CId= " C4 " }
};
// 操作符 Distinct
var stus = slist.Select(stu => stu.CId)
.Distinct();
4、转换操作符 ToArray、ToList
{
List<Student> slist = new List<Student> {
new Student{ SId= " S001 ",SName= " 彭飞 ",SAge= 27,CId= " C2 " },
new Student{ SId= " S002 ",SName= " 张三 ",SAge= 20,CId= " C2 " },
new Student{ SId= " S003 ",SName= " 李四 ",SAge= 25,CId= " C1 " },
new Student{ SId= " S003 ",SName= " 王五 ",SAge= 25,CId= " C4 " }
};
// 转换操作符
Student[] stuArr = slist.Where(stu => stu.SAge < 26)
.ToArray();
List<Student> stuList = slist.Where(stu => stu.SAge < 26)
.ToList();
5、聚合操作符 Min、Max、Sum、Count
{
List<Student> slist = new List<Student> {
new Student{ SId= " S001 ",SName= " 彭飞 ",SAge= 27,CId= " C2 " },
new Student{ SId= " S002 ",SName= " 张三 ",SAge= 20,CId= " C2 " },
new Student{ SId= " S003 ",SName= " 李四 ",SAge= 25,CId= " C1 " },
new Student{ SId= " S003 ",SName= " 王五 ",SAge= 25,CId= " C4 " }
};
// 聚合操作符
var minAge = slist.Min(stu => stu.SAge);
var maxAge = slist.Max(stu => stu.SAge);
var sumAge = slist.Sum(stu => stu.SAge);
var count = slist.Where(stu => stu.SAge < 26).Count();
6、排序
{
List<Student> slist = new List<Student> {
new Student{ SId= " S001 ",SName= " 彭飞 ",SAge= 27,CId= " C2 " },
new Student{ SId= " S002 ",SName= " 张三 ",SAge= 20,CId= " C2 " },
new Student{ SId= " S003 ",SName= " 李四 ",SAge= 25,CId= " C1 " },
new Student{ SId= " S003 ",SName= " 王五 ",SAge= 25,CId= " C4 " }
};
// 排序
var query = slist.OrderBy(stu => stu.CId)
.ThenByDescending(stu => stu.SName)
.ThenBy(stu => stu.SAge);
7、分区(分页)
{
List<Student> slist = new List<Student> {
new Student{ SId= " S001 ",SName= " 彭飞 ",SAge= 27,CId= " C2 " },
new Student{ SId= " S002 ",SName= " 张三 ",SAge= 20,CId= " C2 " },
new Student{ SId= " S003 ",SName= " 李四 ",SAge= 25,CId= " C1 " },
new Student{ SId= " S003 ",SName= " 王五 ",SAge= 25,CId= " C4 " }
};
// 分区
var query = slist.Skip( 1).Take( 2);
谢谢。。。