Linq概述
- Linq(语言集成查询)在C#中集成了查询语法,可以用相同的语法访问不同的数据源。Linq提供了不同数据源的抽象层,所以可以使用相同的语法。
标准的查询操作符
- Where OffType
- 筛选操作符定义了返回元素的条件。在Where查询操作符中可以使用谓词。例如,lambda表达式定义的谓词,来返回布尔值。OfType根据类型筛选元素,只返回TResult类型的元素
- Select SelectMany
- 投射操作符用于把对象转换为另一个类型的新对象。Select和SelectMany定义了根据选择器函数选择结果值得投射
- OrderBy\ThenBy\OrderByDescending\ThenByDescending\ThenByDescending\Reverse
- 排序操作符改变所返回的元素的顺序。OrderBy按升序排序,OrderByDescending按降序排序。如果第一次排序的结果很类似,就可以使用ThenBy和ThenBy Deacending 操作符进行第二次排序。Reverse反转集合中元素的顺序
Join\GroupJoin -连接操作符用于合并并不直接相关的集合。使用Join操作符,可以根据键选择器函数连接两个集合,这个类似于SQL中的JOIN。GroupJoin操作符连接两个集合,组合其结果
GroupBy\ToLookup
Any\All\Contains
Take\Skip\TakeWhile\SkipWhile
Distinct\Union\Intersect\Except\Zip
First\FirstOrDefault\Last\LastOrDefault\ElementAt\ElementAtOrDefault\Single\SingleOrDefault
Count\Sum\Min\Max\Average\Aggregate
ToArray\AsEnumerable\ToList\ToDictionary\Cast
Empty\Range\Repeat
筛选
foreach(var r in rqacers) {
WriteLine($"{r:A}");
}
var racers=Formulal.GetChampions().Where(r=>r.Wins>15 &&(r.Country==“Brazil” || r.Country== “Austria”)).Select(r=>r);
> 用索引筛选
- 不能使用Linq查询的一个例子是Where()方法的重载。在Where()方法的重载中,可以传递第二个参数--索引。索引是筛选器返回的每个结果的计数器。可以在表达式中使用这个索引,执行基于索引的计算。
var racers =Formulal.GetChamplons().Where((r,index)=>r.LastName.StartsWith(“A”) && index%2!=0); foreach (var r in racers) {
WriteLine(${r:A});
}
> 类型筛选
-为了基于类型的筛选,可以使用OfType()扩展方法。这里数组数据包含string和int对象。使用OfType()扩展方法,把string类传送给泛型参数,就从集合中仅返回字符串
object[] data={“one”,2,3,“four”,“five”,6};
var query=data.OfType();
foreach(var s in query)
{
WriteLine(s);
}
> LINQ查询中的变量
- 在为分组编写的LINQ查询中,Count方法调用了多次。使用了let子句可以改变这种方式。let允许在LINQ查询中定义变量:
var countries=Formulal.GetChampions().GroupBy(r=>r.Country).Select(g=>new{Group=g,Count=g.Count()}).OrderByDescending(g=>g.Count).ThenBy(g=>g.Group.Key).Where(g=>g.Count>=2).Select(g=>new {
Country=g.Group.Key,
Count=g.Count
}); ```
内连接
- 使用join子句可以根据特定的条件合并两个数据源,但之前要获得两个要连接的列表。
- 例子:在一级方程式比赛中,有赛车手冠军和车队冠军。赛车手从GetChampions()方法中返回,车队从GetConstructorChampions()方法中返回。现在要获得一个年份表,列出每年的赛车手冠军和车队冠军
- 先定义两个查询,用于查询赛车手和车队
var racers=from r in Formulal.GetChampions() from y in r.Years select new { Year=y, Name=r.FirstName+""+r.LastName }; var teams=from t in Formulal.GetContructorChampions() from y in t.Years select new { Year =y, Name=t.Name };
- 有了这两个查询,再通过join子句,根据赛车手获得冠军的年份和车队获得冠军的年年份进行连接。select子句定义了一个新的匿名类型,它包含Year、Racer和Team属性。 ``` var racersAndTeams=(from r in racers join t in teams on r.Year equals t.Year select new { r.Year, Champion=r.Name, Constructor=t.Name }).Take(10); WriteLine(“Year World Champion\t Constructor Title”); foreach (var item in racersAndTeams) { WriteLine($“{item.Year}:{item.Champion,-20}{item.Constructor}”); } 也可以把它们合并为一个LINQ查询 var racersAndTeams= { from r in from r1 in Formulal.GetChampions() from yr in r1.Years select new { Year=yr, Name=r1.FirstName + “” +r1.LastName } join t in from t1 in Formulal.GetContructorChampios
}
```