1.LINQ
LINQ(Language Integrated Query)
定义:语言集成查询是一组用于c#和Visual Basic语言的扩展。它允许编写C#或者Visual Basic代码以操作内存数据的方式,查询数据库。
通过使用查询语法,您甚至可以使用最少的代码对数据源执行复杂的筛选、排序和分组操作。 您使用相同的基本查询表达式模式来查询和转换 SQL 数据库、ADO.NET 数据集、XML 文档和流以及 .NET 集合中的数据。
2.Lambda表达式
定义:Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数
3.常用查询指令
①.基本查询
var query = from r in listStudents where r.score < 60 orderby r.score descending select r;
//var q2 = listStudents.Where(r => r.score < 60).OrderByDescending(r => r.score).Select(r => r) ;//或使用Lambda表达式
②.延迟查询属性
linq查询为延迟查询,只需构造一次查询语句,可以多次使用
/// <summary>
/// Linq
/// 延迟查询
/// linq查询为延迟查询,只需构造一次查询语句,可以多次使用
/// </summary>
static void Linq2()
{
#region 构造查询数据
List<string> lists = new List<string> { "Jack","Pet","Hant","Li","Kkk"};
#endregion
var query = from r in lists where r.StartsWith("J") select r;
Console.WriteLine("第一次查询结果:");
foreach (string st in query)
{
Console.WriteLine( st);
}
Console.WriteLine("第二次查询结果:");
lists.Add("Jone");
lists.Add("Jimi");
lists.Add("Johu");
foreach (string st in query)
{
Console.WriteLine(st);
}
Console.ReadKey();
/*
输出结果:
* 第一次:Jack
* 第二次:Jack Jone Jimi Johu
*/
}
③.类型筛选
利用OfType方法可以把特定类型数据筛选出来。
/// <summary>
/// Linq类型筛选-ofType
/// </summary>
static void Linq3()
{
object[] pList = new object[] { 1,"one",2,"two",3,"three"};
var query = pList.OfType<string>();
foreach (var st in query)
{
Console.WriteLine(st);
}
Console.ReadKey();
/*
输出结果:
* one two three
*/
}
④.复合from子句
var query = from s in listStudents
from n in s.name
where n == '赵' orderby s.score descending
select s.grade + "班-" + s.name + ",分数" + +s.score;
/*查询出所有姓赵的学生的班级、姓名、分数信息,并按分数由高到低排序*/
⑤.多级排序
//参数越靠前,优先级越高
//先按score排序,当分数相同时再按grade排序...依次类推
var query = from s in listStudents orderby s.score, s.grade, s.age, s.name select s;
⑥.分组
//按国家分组,并选出大于2的组,形成新的集合
var query = from r in listChampion
group r by r.country into g
orderby g.Count() descending, g.Key
where g.Count() >= 2
select
new { country = g.Key, count = g.Count() };
⑦.联合查询-join
//查询出集合qSt中year等于集合qSc中year的元素并形成新的集合
var qjoin = from r in qSt
join c in qSc
on r.year equals c.year
select new
{
Year = r.year,
stName = r.name,
scName = c.name
};
⑧.合并-zip()
/*若合并两项项数不同,则在达到较小集合的末尾时停止*/
var qZip = qSc.Zip(qSt, (first, second) =>string.Format("Year:{0},Name:{1}.", first.Year,second.Name));//返回值qZip为字符串集合
⑨.分区(分页)
通过Take()和Skip()实现只显示部分查询结果。
//通过skip跳过指定数量的元素,再通过take提取固定长度元素,可实现分页
var qr = (from r in listStudents orderby r.score descending select r).Skip(i * pageSize).Take(5);
//var qr2 = listStudents.OrderByDescending(r => r.score).Select(r => r).Skip(i * pageSize).Take(5);//或
⑨.并行linq
并行查询可以分解查询的工作,使其分布在多个线程上。当pc拥有多个cpu时,可以看到并行查询带来的改进效果。并行LINQ适用于大型的集合查询,并拥有一定的优势。使用System.Collections.Concurrent.Partitioner.Create可以手动创建分区器。
var sum2 = (from x2 in data.AsParallel() where x2 > 20 select x2).Sum();//并行查询
//var sum3 = data.AsParallel().Where(x3 => x3 > 20).Sum();//或并行查询(Lambda表达式)
⑩.取消长时间运行的并行linq查询
对于并行ling而言,可以设置可以利用System.Threading.CancellationTokenSource设置取消操作。
//通过.WithCancellation(cts.Token)设置
var sum = (from x in data.AsParallel().WithCancellation(cts.Token) where x < 20 select x).Average();
⑪.复杂左关联
var data = from c in db.T_COURSE
join u in db.T_USER_COURSE_RECORD.Where(x=>x.USER_ID ==userId)
on c.COURSE_ID equals u.COURSE_ID into x
from cx in x.DefaultIfEmpty()
select new
{
c.COURSE_NAME,
COURSE_ID=cx,
USER_COURSE_ID=cx==null?0:cx.USER_COURSE_ID,
USER_ID= cx,
SCORE =( cx==null|cx.SCORE == -1) ? "未完成" : cx.SCORE.ToString()
};