C# Linq查询的基本练习

来源:互联网 发布:淘宝上添加剂少的零食 编辑:程序博客网 时间:2024/06/05 22:37

在C#中利用Linq进行一些集合的操作是十分方便的,传统的一些编程方式自然也能相同的功能,不过使用Linq更加的优雅。

 

C#的一些高级语言特性确实令人着迷。

 

我这边就直接通过几个例子来展现一下Linq的强大,就不说逐字逐句的扣语法了。

 

Linq之前:

在写Linq之前有几个C#新的知识点必须掌握才能学习它。

 

1.匿名对象:

学过Java的同学知道匿名对象的强大之处,一个接口可以直接通过new关键字来产生一个对象,在new的过程中可以指定需要override的方法,填加新的字段。

 

不过在C#中,Java的匿名对象被分为了两个知识点,一个是delegate,另一个就是现在要说的匿名对象,在C#中的匿名对象只能添加字段,而不能添加方法。

 

例子如下:

var psn = new { name = "小明" };Console.WriteLine(psn.name);

因为只能添加字段,所以平时大家也不常用,可以说这个东西是专门为Linq准备的。

 

2.lambda表达式:

上面说了delegate,而delegate的创建方式有两种,一种是直接把类中的函数赋值进去,另一种是匿名函数,也就这边的lambda表达式了。

 

关于delegate实际上是一种将方法(函数)作为对象存储到变量中的一种技术,如果对这个不是很了解,建议写几个程序练习一下。

 

这边给出lambda和普通函数的对比:

static void Main_Delegate(string[] args){    Action method_lambda = () =>    {        Console.WriteLine("Hello");    };    Action method_normal = PrintHello;    method_lambda();    method_normal();}static void PrintHello(){    Console.WriteLine("Hello");}

正式Linq的练习:

首先在写之前,需要知道Linq其实就是对集合提供类似于sql一般的操作。

 

我们准备好今天需要查询的数据:

class Person{    public string name;    public int age;    public override string ToString()    {        return "name: " + name + ", age: " + age;    }}class Course{    public string personName;    public string name;    public int score;    public override string ToString()    {        return "name: " + name + ", score: " + score + ", personName: " + personName;    }}List<Person> list = new List<Person>();list.Add(new Person(){ name = "小明", age = 19});list.Add(new Person(){ name = "小红", age = 17});list.Add(new Person(){ name = "小强", age = 20});List<Course> list2 = new List<Course>();list2.Add(new Course(){ personName = "小明", name = "数学", score = 90});list2.Add(new Course(){ personName = "小明", name = "英语", score = 56});list2.Add(new Course(){ personName = "小红", name = "数学", score = 60});list2.Add(new Course(){ personName = "小红", name = "英语", score = 100});

一些人和他们本次考试的成绩。

 

1.马上来做第一个查询,查询所有年龄大于18岁的人:

from p in listwhere p.age > 18select p

这就是一个最简单的查询了,需要记住的是每个查询都是以from ... in ...开头,select或group结尾。

 

Linq有两种表达形式,一种就是以上类似于sql的表达式,另一种是使用IEnumerable的扩展方法:

list.Where(p=>p.age>18);

效果是一样的,都属于Linq。这边再提一个方法,List的FindAll方法:

list.FindAll(p => p.age > 18);

通过以上的方式,返回的结果和上面两种方式是一模一样的,不过FindAll方法属于List,而上面两种Linq是基于IEnumerable接口的,所以我们知道了,Linq的集合接口的基础就是IEnumerable,只要实现了该接口的集合就能做Linq操作。

 

第一个说的可能比较多,下面就快了。

 

2.多集合查询,查询所有及格的课程对应的人:

from p in listfrom c in list2where c.personName == p.name && c.score >= 60select new{c, p}list.SelectMany(c=>list2, (person, course) => new {person, course} ).Where(x=>x.course.personName==x.person.name & x.course.score>=60)

这边SelectMany将list和list2映射到一个新的匿名集合,这边我取名为x,而两个新的集合名分别为person和course。

 

3.使用Join代替多集合查询:

from p in listjoin c in list2 on p.name equals c.personNamewhere c.score >= 60select new { c, p }list.Join(list2, p=>p.name, c=>c.personName, (p, c) => new { c, p }).Where(x=>x.c.score >= 60)

跟上面的多集合查询效果是一样的,只不过就是把相等条件提取出来了而已。

 

4.使用into关键字,查询选课数量:

from p in list join c in list2 on p.name equals c.personNameinto groupsselect new { p.name, count = groups.Count() }list.GroupJoin(list2, p=>p.name, c=>c.personName, (p, cs)=>new{p.name, count=cs.Count()})

通过from和join之后产生了一个大集合,而into将p为同一个的查询记录放到同一个集合groups中。

 

也就是将同一个人的课程放到groups集合中,调用groups.Count()自然是课程的数量

 

5.查询课程选修的人数:

from c in list2group c by c.name into csselect new {name=cs.Key, count=cs.Count()}list2.GroupBy(c=>c.name).Select((cs)=>new{name=cs.Key, count=cs.Count()})

使用group by关键字将课程名相同的放到一个集合中,原理跟上面查询是一样。

 

以上是几个基本的练习,感觉掌握了这些,面对大部分需求应该是没有问题的了,以后学到了新的还会继续补充。


6.从0遍历到99:

from i in Enumerable.Range(0, 99) select i


7.99重复10遍:

from i in Enumerable.Repeat(99, 10) select i