C#中的LINQ

Posted Hello Bug.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中的LINQ相关的知识,希望对你有一定的参考价值。

一:什么是LINQ

LINQ代表语言集成查询,是.net框架的扩展,它允许我们用SQL查询数据库的方式来查询数据的集合
LINQ可以让代码更加简洁,但LINQ在执行过程中会产生一些临时变量,而且会用到委托,所以会产生一定的垃圾内存从而影响运行时的效率


二:LINQ延迟查询的特性

延迟查询是指查询操作并不是在定义的时候执行,而是在使用集合中的数据时才执行

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        var list = personList.Where((p) => p.Age < 30);

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }

        personList.Add(new Person() { Id = 4, Name = "小赵", Age = 15, Score = 100 });

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

三:用法

——select:返回值

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        var list = personList.Select(p => p.Name);
        var list = personList.Select(p => new { id = p.Id, name = p.Name });

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

——where:查询特定条件

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        //1.表达式写法
        var list = from p in personList
                   where p.Score >= 80 && p.Age < 50
                   select p;
        //2.扩展方法写法
        var list = personList.Where((p) => p.Score >= 80 && p.Age < 50);

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

——OfType:查询特定数据类型 

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<object> objList = new List<object>()
    {
        "test1",
        1,
        1.34f,
        "test2",
    };

    static void Main(string[] args)
    {
        var list = objList.OfType<string>();

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

——join in:联合查询,将一个集合与另一个集合合并

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };
    static List<Reward> rewardList = new List<Reward>()
    {
        new Reward(){ Id=1,Score=100,RewardName="奖励1"},
        new Reward(){ Id=2,Score=80,RewardName="奖励2"},
        new Reward(){ Id=3,Score=60,RewardName="奖励3"},
    };

    static void Main(string[] args)
    {
        //1.表达式写法1
        var list = from p in personList
                   from r in rewardList
                   where p.Score >= 80 && p.Score == r.Score
                   select new { pList = p, rList = r };
        //2.表达式写法2
        var list = from p in personList
                   join r in rewardList on p.Score equals r.Score
                   where p.Score >= 80
                   select new { pList = p, rList = r };
        //3.扩展方法写法
        var list = personList.Join(rewardList, p => p.Score, r => r.Score, (p, r) => new { pList = p, rList = r });

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

class Reward
{
    public int Id;
    public int Score;
    public string RewardName;

    public override string ToString()
    {
        return Id + "," + Score + "," + RewardName;
    }
}

——orderby:对集合排序,默认是从小到大排序

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=60,Score=60},
        new Person(){ Id=3,Name="小刘",Age=60,Score=80},
    };

    static void Main(string[] args)
    {
        //1.表达式写法
        var list = from p in personList
                    orderby p.Age,p.Score descending//添加descending是从大到小排序
                    select p;
        //2.扩展方法写法
        var list = personList.OrderBy((p) => p.Age).ThenBy((p) => p.Score);

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

——group by:自身分组查询

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        //1.表达式写法
        var list = from p in personList
                   group p by p.Score into g
                   select new { count = g.Count(), k = g.Key };//key代表是按照什么分组的

        //2.扩展方法写法
        var list = personList.GroupBy((p) => p.Score)
            .Select((g, count) => new { g = g.Key, count = g.Count() });

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

——Any和All:判断集合中是否满足某个/条件

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        bool b1 = personList.Any((p) => p.Age < 50);
        bool b2 = personList.All((p) => p.Age < 50);

        Console.WriteLine(b1);
        Console.WriteLine(b2);
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

——Skip:跳过指定个元素查询

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        var list = personList.Skip(1);

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

——Take:只查询指定个元素

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        var list = personList.Take(2);

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

——Sum、Average、Max、Min:计算集合中指定数字类型数据的总和、平均值、最大值、最小值

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        var sum = personList.Sum((p) => p.Age);
        var avg = personList.Average((p) => p.Age);
        var max = personList.Max((p) => p.Age);
        var min = personList.Min((p) => p.Age);

        Console.WriteLine(sum);
        Console.WriteLine(avg);
        Console.WriteLine(max);
        Console.WriteLine(min);
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

——Concat: 连接两个相同类型集合,合并为一个集合(只能操作字符串类型或数字类型的集合)

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<int> numList1 = new List<int>() { 1, 2, 3 };
    static List<int> numList2= new List<int>() { 4, 5, 6 };

    static void Main(string[] args)
    {
        var list = numList1.Concat(numList2);

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

——Distinct:从集合中去除掉重复的元素(只能操作字符串类型或数字类型的集合)

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<int> numList = new List<int>() { 1, 2, 3, 1, 2, 3 };

    static void Main(string[] args)
    {
        var list = numList.Distinct();

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

——Except:从集合中去除掉另一个集合中的元素(只能操作字符串类型或数字类型的集合)

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<int> numList1 = new List<int>() { 1, 2, 3 };
    static List<int> numList2 = new List<int>() { 1, 2, 4 };

    static void Main(string[] args)
    {
        var list = numList1.Except(numList2);

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

——ElementAt:得到集合中指定索引的元素,与[]作用相同

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<int> numList = new List<int>() { 1, 2, 3};

    static void Main(string[] args)
    {
        var value = numList.ElementAt(2);

        Console.WriteLine(value);
    }
}

 ——Count:得到集合中满足指定条件的元素个数

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<int> numList1 = new List<int>() { 1, 2, 3 };

    static void Main(string[] args)
    {
        var count = numList1.Count((n) => n >= 2);

        Console.WriteLine(count);
    }
}

——First/Single和Last:得到集合中第一个/最后一个元素(如果集合中包含多个元素,使用Single会报错)

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<int> numList1 = new List<int>() { 1, 2, 3 };

    static void Main(string[] args)
    {
        var value1 = numList1.First((n) => n >= 2);
        var value2 = numList1.Last((n) => n < 3);

        Console.WriteLine(value1);
        Console.WriteLine(value2);
    }
}

——ToDictionary:将集合转换为字典 

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        var list = personList.ToDictionary(p => p.Id);

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

——ToList: 将集合转换为list

using System;
using System.Collections.Generic;
using System.Linq;

class MainClass
{
    static List<Person> personList = new List<Person>()
    {
        new Person(){ Id=1,Name="小明",Age=20,Score=100},
        new Person(){ Id=2,Name="小王",Age=40,Score=80},
        new Person(){ Id=3,Name="小刘",Age=60,Score=60},
    };

    static void Main(string[] args)
    {
        var dict = personList.ToDictionary(p => p.Id);
        List<Person> list = dict.Values.ToList();

        foreach (var temp in list)
        {
            Console.WriteLine(temp);
        }
    }
}

class Person
{
    public int Id;
    public string Name;
    public int Age;
    public int Score;

    public override string ToString()
    {
        return Id + "," + Name + "," + Age + "," + Score;
    }
}

以上是关于C#中的LINQ的主要内容,如果未能解决你的问题,请参考以下文章

C#中的LINQ

在 C# 代码中的 DB 中的 Linq 查询中包含空单元格

C# 之 LINQ简析

C#中的LINQ

编写高质量代码改善C#程序的157个建议——建议30:使用LINQ取代集合中的比较器和迭代器

LINQ C# 中的条件计数分组依据