【C#】Linq基本操作

介绍一下

Linq 是.NET Fraemork3.5 引入的一个新功能

 

接下来,将是一些基本操作

 

首先,新建Student类,存储数据

public class Student
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public int Sex { get; set; }//1为男,0为女
    public int SourseID { get; set; }

    public override string ToString()
    {
        return string.Format("ID:{0},Name:{1},Age:{2},Sex:{3},SourseID:{4}", ID, Name, Age, Sex, SourseID);
    }
}

创建一些数据

List<Student> students = new List<Student>()
{
    new Student(){ ID = 0,Name = "哈哈",Age = 18,Sex = 1,SourseID=1001},
    new Student(){ ID = 1,Name = "啊啊",Age = 23,Sex = 0,SourseID=1002},
    new Student(){ ID = 2,Name = "嘻嘻",Age = 19,Sex = 1,SourseID=1001},
    new Student(){ ID = 3,Name = "呵呵",Age = 22,Sex = 1,SourseID=1003},
    new Student(){ ID = 4,Name = "呜呜",Age = 17,Sex = 0,SourseID=1002},
    new Student(){ ID = 4,Name = "呜呜",Age = 17,Sex = 0,SourseID=1002},
    new Student(){ ID = 5,Name = "咔咔",Age = 22,Sex = 1,SourseID=1002}
};

 

 

查询所有年龄大于20的学生

 

首先看看用foreach循环查询

var res1 = new List<Student>();
foreach (var st in students)
{
    if (st.Age > 20)
        res1.Add(st);
}

输出

foreach (var item in res1)
{
    Console.WriteLine(item.ToString());
}
Console.WriteLine("--------------------------------");

 

再看看用Linq

var res12 = from st in students where st.Age > 20 select st;

 

也可以使用扩展方法

Func<Student, bool> func = st => st.Age > 20;
var res13 = students.Where(func);

使用Func遍历集合中的每一个元素,符合条件的返回true

可以简写成

var res14 = students.Where(st => st.Age > 20);

从上面可以看出,使用Linq,比foreach循环查询,代码更简洁

 

结果是一个 IEnumerable<Student> 对象,可以使用ToList() 方法转成List<Sutdent> 对象

List<Student> res15 = (from st in students where st.Age > 20 select st).ToList();
List<Student> res16 = students.Where(st => st.Age > 20).ToList();

 

 

查询所有年龄大于20且性别为男的学生

Linq

var res21 = from st in students where st.Age > 20 && st.Sex == 1 select st;

扩展方法

var res22 = students.Where(st => st.Age > 20 && st.Sex == 1);

 

集合查询

Union 并集,去除重复

Concat 并集,连接两个序列

Intersect 交集,返回两个序列相同的元素

Except 差集
 

var res41= (from st in students where st.Age > 20 select st);
var res42 = (from st in students where st.Age > 18 select st);

var res43 = (from st in students where st.Age > 20 select st).Union(from st in students where st.Age > 18 select st);

输出

 

序列排序

正序

var res51 = from st in students where st.Age > 20 orderby st.Age select st;

倒序 

var res52 = from st in students where st.Age > 20 orderby st.Age descending select st;

多个字段排序

var res53 = from st in students where st.Age > 20 orderby st.Age, st.ID select st;

 

扩展方法

var res54 = students.Where(st => st.Age > 20).OrderBy(st => st.Age).ThenBy(st => st.ID);

当多个字段排序时,如果同时两个OrderBy时,使用第二OrderBy排序会对结果进行重新排序,所以想在上一次排序结果的基础上继续排序要用ThenBy

OrderBy 正序 , OrderByDescending 倒序

ThenBy 正序 , ThenByDescending 倒序
 

 

查询元素

First 返回序列中满足条件的第一个元素,如果不存在满足条件的元素,则会引发异常:“序列不包含任何匹配元素”

var res31 = students.First(st => st.Age == 22);

FirstOrDefault 返回序列中满足条件的第一个元素;如果未找到这样的元素,则返回默认值 (默认值:值类型默认值为0,应用类型默认值为null)

 

var res32 = students.FirstOrDefault(st => st.Age == 29);//未找到返回值为null

List<T> 的Find 返回序列中满足条件的第一个元素;如果未找到这样的元素,则返回默认值

 var res33= students.Find(st => st.Age == 22);

 

Last 返回序列中满足指定条件的最后一个元素,如果不存在满足条件的元素,将抛出异常

LastOrDefault 返回序列中满足条件的最后一个元素;如果未找到这样的元素,则返回默认值 

var res34 = students.Last (st => st.Age == 22);

 

Single 返回序列中满足指定条件的唯一元素;如果有多个这样的元素存在,则会引发异常

var res35 = students.Single(st => st.Age == 22);

SingleOrDefault 返回序列中满足指定条件的唯一元素;如果这类元素不存在,则返回默认值;如果有多个元素满足该条件,此方法将引发异常

var res36 = students.SingleOrDefault(st => st.Age == 22);

 

ElementAt 返回序列中指定索引处的元素。索引从0开始,如果索引超出范围,此方法将引发异常

 var res37 = students.ElementAt(0);

ElementAtOrDefault 返回序列中指定索引处的元素;如果索引超出范围,则返回默认值

var res38 = students.ElementAtOrDefault(10);//null

 

判断列表中是否有年龄为18的学生

bool isExist = students.Any(st => st.Age == 18);

判断列表中是否所有的学生年龄都为18

bool isExist2 = students.All(st => st.Age == 18);//false

 

计算

 

Count() 返回序列中的元素数量

LongCount() 返回序列中的元素数量

Sum() 计算序列中指定列之和

Max() 返回序列中指定列的最大值

Min() 返回序列中指定列的最小值

Average() 计算序列中指定列平均值

Aggregate() 对序列应用累加器函数

 

查询年龄大于20岁的学生人数

int count = students.Where(st => st.Age > 20).Count();

计算所有学生的年龄之和

int sum = students.Select(st=>st.Age).Sum();

计算所有学生的年龄最小值

int max = students.Select(st => st.Age).Max();

 

也可以对List<T>进行操作 

List<int> Nos = new List<int>() { 5,6,7,8,9 };
int NosSum = Nos.Sum();
double ave = Nos.Average();

 

Aggregate() 对序列应用累加器函数

//5+6+7+8+9
int agg1 = Nos.Aggregate((re, n) => re + n);
//3+5+6+7+8+9   3为累加器的初始值
int agg2 = Nos.Aggregate(3,(re, n) => re + n);
//(3+5+6+7+8+9)*3
int agg3 = Nos.Aggregate(3, (re, n) => re + n, res => res * 3);

 

新建Sourse类,存储数据

public class Sourse
{
    public int ID { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return string.Format("ID:{0},Name:{1}", ID, Name);
    }
}

创建一些数据

List<Sourse> sourses = new List<Sourse>()
{
     new Sourse(){ ID = 1001,Name="C#基础"},
     new Sourse(){ ID = 1002,Name="HTML基础"},
     new Sourse(){ ID = 1003,Name="SQL基础"}
};

 

联合查询

查询两个序列

 

查询课程名称为“C#基础”的学生

Linq

var res61 = from st in students
            from so in sourses
            where st.SourseID == so.ID && so.Name == "C#基础"
            select new { student = st, sourse = so };//创建临时对象

扩展方法

var res62 = students.SelectMany(st => sourses, (st, so) => new { student = st, sourse = so })
    .Where(s => s.student.SourseID == s.sourse.ID && s.sourse.Name == "C#基础");

输出

使用join on联合查询

注意判断相等要用equals

var res63 = from st in students
            join so in sourses on st.SourseID equals so.ID
            where st.SourseID == so.ID && so.Name == "C#基础"
            select new { student = st, sourse = so };

 

对结果进行分组操作(把学生按照课程分类,看哪个课程选的人数最多)

var res64 = from so in sourses
            join st in students on so.ID equals st.SourseID
            into groups
            orderby groups.Count()
            select new { sourse = so, count = groups.Count() };

输出

 

group by 按照自身字段分组

按照性别分组

var res65 = from st in students
            group st by st.Sex
            into g
            select new { count = g.Count(), key = g.Key };//key 表示时按照那个字段分组

输出

 




 

下面是我测试过程的所有代码,其实就是上面的代码(拿去用)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleTest
{
    class Program
    {

        static void Main(string[] args)
        {
            //创建一些数据
            List<Student> students = new List<Student>()
            {
                new Student(){ ID = 0,Name = "哈哈",Age = 18,Sex = 1,SourseID=1001},
                new Student(){ ID = 1,Name = "啊啊",Age = 23,Sex = 0,SourseID=1002},
                new Student(){ ID = 2,Name = "嘻嘻",Age = 19,Sex = 1,SourseID=1001},
                new Student(){ ID = 3,Name = "呵呵",Age = 22,Sex = 1,SourseID=1003},
                new Student(){ ID = 4,Name = "呜呜",Age = 17,Sex = 0,SourseID=1002},
                new Student(){ ID = 4,Name = "呜呜",Age = 17,Sex = 0,SourseID=1002},
                new Student(){ ID = 5,Name = "咔咔",Age = 22,Sex = 1,SourseID=1002}
            };


            //查询所有年龄大于20的学生

            //首先看看用foreach循环查询 
            var res1 = new List<Student>();
            foreach (var st in students)
            {
                if (st.Age > 20)
                    res1.Add(st);
            }
            //输出
            foreach (var item in res1)
            {
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine("--------------------------------");

            //再看看用Linq
            var res12 = from st in students where st.Age > 20 select st;

            //也可以使用扩展方法
            Func<Student, bool> func = st => st.Age > 20;
            var res13 = students.Where(func);
            //使用Func遍历集合中的每一个元素,符合条件的返回true

            //可以简写成
            //扩展方法
            var res14 = students.Where(st => st.Age > 20);
            //从上面可以看出,使用Linq,比foreach循环查询,代码更简洁

            //结果是一个 IEnumerable<Student> 对象,可以使用ToList() 方法转成List<Sutdent> 对象
            List<Student> res15 = (from st in students where st.Age > 20 select st).ToList();
            List<Student> res16 = students.Where(st => st.Age > 20).ToList();



            //查询所有年龄大于20且性别为男的学生
            //Linq
            var res21 = from st in students where st.Age > 20 && st.Sex == 1 select st;
            //扩展方法
            var res22 = students.Where(st => st.Age > 20 && st.Sex == 1);

            foreach (var item in res22)
            {
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine("--------------------------------");


            //集合查询
            //Union 并集,去除重复
            //Concat 并集,连接两个序列
            //Intersect 交集,返回两个序列相同的元素
            //Except 差集

            var res41 = (from st in students where st.Age > 20 select st);
            var res42 = (from st in students where st.Age > 18 select st);

            var res43 = (from st in students where st.Age > 20 select st).Union(from st in students where st.Age > 18 select st);


            foreach (var item in res41)
            {
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine("--------------------------------");
            foreach (var item in res42)
            {
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine("--------------------------------");
            foreach (var item in res43)
            {
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine("--------------------------------");


            //序列排序
            //正序
            var res51 = from st in students where st.Age > 20 orderby st.Age select st;
            //倒序 
            var res52 = from st in students where st.Age > 20 orderby st.Age descending select st;
            //多个字段排序
            var res53 = from st in students where st.Age > 20 orderby st.Age, st.ID select st;
            //扩展方法
            var res54 = students.Where(st => st.Age > 20).OrderBy(st => st.Age).ThenBy(st => st.ID);
            //当多个字段排序时,如果同时两个OrderBy时,使用第二OrderBy排序会对结果进行重新排序,所以想在上一次排序结果的基础上继续排序要用ThenBy
            //OrderBy 正序 , OrderByDescending 倒序
            //ThenBy 正序 , ThenByDescending 倒序
            Console.WriteLine("--------------------------------");


            //查询元素

            //First 返回序列中满足条件的第一个元素,如果不存在满足条件的元素,则会引发异常:“序列不包含任何匹配元素”
            var res31 = students.First(st => st.Age == 22);
            //FirstOrDefault 返回序列中满足条件的第一个元素;如果未找到这样的元素,则返回默认值 (默认值:值类型默认值为0,应用类型默认值为null)
            var res32 = students.FirstOrDefault(st => st.Age == 29);//未找到返回值为null

            //List<T> 的Find 返回序列中满足条件的第一个元素;如果未找到这样的元素,则返回默认值
            var res33 = students.Find(st => st.Age == 22);

            //Last 返回序列中满足指定条件的最后一个元素,如果不存在满足条件的元素,将抛出异常
            //LastOrDefault 返回序列中满足条件的最后一个元素;如果未找到这样的元素,则返回默认值 
            var res34 = students.Last(st => st.Age == 22);

            //Single 返回序列中满足指定条件的唯一元素;如果有多个这样的元素存在,则会引发异常
            var res35 = students.Single(st => st.Age == 19);
            //SingleOrDefault 返回序列中满足指定条件的唯一元素;如果这类元素不存在,则返回默认值;如果有多个元素满足该条件,此方法将引发异常
            var res36 = students.SingleOrDefault(st => st.Age == 19);

            //ElementAt 返回序列中指定索引处的元素。索引从0开始,如果索引超出范围,此方法将引发异常
            var res37 = students.ElementAt(0);
            //ElementAtOrDefault 返回序列中指定索引处的元素;如果索引超出范围,则返回默认值
            var res38 = students.ElementAtOrDefault(10);//null

            //Count() 返回序列中的元素数量
            //LongCount() 返回序列中的元素数量
            //Sum() 计算序列中指定列之和
            //Max() 返回序列中指定列的最大值
            //Min() 返回序列中指定列的最小值
            //Average() 计算序列中指定列平均值
            //Aggregate() 对序列应用累加器函数
            //查询年龄大于20岁的学生人数
            int count = students.Where(st => st.Age > 20).Count();
            //计算所有学生的年龄之和
            int sum = students.Select(st => st.Age).Sum();
            //计算所有学生的年龄最小值
            int max = students.Select(st => st.Age).Max();

            //也可以对List<T>进行操作 
            List<int> Nos = new List<int>() { 5, 6, 7, 8, 9 };
            int NosSum = Nos.Sum();
            double ave = Nos.Average();

            //5+6+7+8+9
            int agg1 = Nos.Aggregate((re, n) => re + n);
            //3+5+6+7+8+9   3为累加器的初始值
            int agg2 = Nos.Aggregate(3, (re, n) => re + n);
            //(3+5+6+7+8+9)*3
            int agg3 = Nos.Aggregate(3, (re, n) => re + n, res => res * 3);


            Console.WriteLine("--------------------------------");

            //判断列表中是否有年龄为18的学生
            bool isExist = students.Any(st => st.Age == 18);
            //判断列表中是否所有的学生年龄都为18
            bool isExist2 = students.All(st => st.Age == 18);//false


            //新建Sourse类,存储数据

            //创建一些数据
            List<Sourse> sourses = new List<Sourse>()
            {
                 new Sourse(){ ID = 1001,Name="C#基础"},
                 new Sourse(){ ID = 1002,Name="HTML基础"},
                 new Sourse(){ ID = 1003,Name="SQL基础"}
            };

            //联合查询
            //查询两个序列
            //查询课程名称为“C#基础”的学生
            //Linq
            var res61 = from st in students
                        from so in sourses
                        where st.SourseID == so.ID && so.Name == "C#基础"
                        select new { student = st, sourse = so };//创建临时对象
            //扩展方法
            var res62 = students.SelectMany(st => sourses, (st, so) => new { student = st, sourse = so })
                .Where(s => s.student.SourseID == s.sourse.ID && s.sourse.Name == "C#基础");

            //使用join on联合查询
            //注意判断相等要用equals
            var res63 = from st in students
                        join so in sourses on st.SourseID equals so.ID
                        where st.SourseID == so.ID && so.Name == "C#基础"
                        select new { student = st, sourse = so };

            //对结果进行分组操作(把学生按照课程分类,看哪个课程选的人数最多)
            var res64 = from so in sourses
                        join st in students on so.ID equals st.SourseID
                        into groups
                        orderby groups.Count()
                        select new { sourse = so, count = groups.Count() };

            //group by 按照自身字段分组
            //按照性别分组
            var res65 = from st in students
                        group st by st.Sex
                        into g
                        select new { count = g.Count(), key = g.Key };//key 表示时按照那个字段分组


            foreach (var item in res65)
            {
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine("--------------------------------");

            Console.ReadKey();
        }
    }

    //Linq 是.NET Fraemork3.5 引入的一个新功能

    //首先,新建Student类,存储数据

    public class Student
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public int Sex { get; set; }//1为男,0为女
        public int SourseID { get; set; }

        public override string ToString()
        {
            return string.Format("ID:{0},Name:{1},Age:{2},Sex:{3},SourseID:{4}", ID, Name, Age, Sex, SourseID);
        }
    }

    public class Sourse
    {
        public int ID { get; set; }
        public string Name { get; set; }

        public override string ToString()
        {
            return string.Format("ID:{0},Name:{1}", ID, Name);
        }
    }
}

 

相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页