C# Linq查询的基本练习

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

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

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

Linq之前:

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

1.匿名对象:

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

扫描二维码关注公众号,回复: 1879621 查看本文章

不过在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 list
where p.age > 18
select 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 list
from c in list2
where c.personName == p.name && c.score >= 60
select 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 list
join c in list2 on p.name equals c.personName
where c.score >= 60
select 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.personName
into groups
select 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 list2
group c by c.name into cs
select 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



猜你喜欢

转载自blog.csdn.net/u012632851/article/details/78825526