Linq的理解

前面的话

这篇文章主要是在工具书中linq的基础上,我做了一些归纳。

目录

  • 什么是Linq
  • 方法语法和查询语法
  • 查询表达式的结构
  • 标准查询运算符

什么是Linq?

  • Linq(link)代表语言集成查询(Language Integrated Query)
  • Linq是.NET框架的扩展,它允许我们以使用SQL查询数据库的方式来查询数据集合。
  • 使用Linq,你可以从数据库、程序对象的集合以及XML文档中查询数据。

一个例子

static void Main()
{
    int[] numbers = {2,12,5,15};//数据源
    IEnumerable<int> lowNums =
                              from n in numbers
                              where n < 10
                              select n;
     foreach(var x in lowNums) //执行查询
         Console.Write("{0},",x);
}

方法语法和查询语法

我们在写Linq查询时可以使用两种形式的语法:查询语法和方法语法。

  1. 方法语法使用标准的方法调用。这些方法是一组叫做查询运算符的方法。例:numbers.Where ( x => x < 20);
  2. 查询语法看上去和SQL语句很相似,使用查询表达式书写。
    例: from n in numbers
    where n < 10
    select n;

查询表达式的结构

  • 子句必须按照一定的顺序出现
  • from 子句和 select … group子句这两部分是必需的。
  • 其他子句是可选的。
  • 在Linq查询表达式中,select子句在表达式最后。
  • 可以有任意多的from… let… where子句
    from子句、join子句、

    class Program
    {
        public class Student
        {                  // 声明类
            public int  StID;
            public string LastName;
        }
    
        public class CourseStudent 
        {
            public string CourseName;
            public int StID;
        }
    //初始化数组
    static Student[] students = new Student[] {
         new Student { StID =1,LastName ="Carson"},
         new Student{ StID= 2,LastName="Klassen"}, 
         new Student{ StID =3,LastName = "Fleming"}
     };
     static CourseStudent[] studentsInCourses = new CourseStudent[] 
     {
         new CourseStudent { CourseName = "Art", StID =1},
         new CourseStudent {CourseName ="Art",StID=2},
         new CourseStudent {CourseName ="History",StID=1},
         new CourseStudent {CourseName ="History",StID=3},
         new CourseStudent {CourseName ="Physics",StID=3} 
     };
    
    static void Main()
    {
      //查找所有选择了历史课的学生的姓氏
        var query = from s in students
                            join c in studentsInCourses on s.StID equals c.StID
                            where c.CourseName == "History"
                            select s.LastName;
        foreach(var q in query)
            Console.WriteLine("Student taking History:{0},"q);
    }
    }

    from… let… where

static void Main()
{
    var groupA = new[]{3,4,5,6};
    var groupB = new[]{6,7,8,9};
    var someInts = from a in groupA
                   from b in groupB
                   let sum = a+b
                   where sum == 12
                   select new {a,b,sum};
    foreach(var a in someInts)
        Console.WriteLine(a);
}
static void Main()
{
    var groupA = new[]{3,4,5,6};
    var groupB = new[]{6,7,8,9};

    var someInts = from int a in groupA
                   from int b in groupB
                   let sum = a+b
                   where sum>=11
                   where a==4
                   select new{a , b ,sum}; 
    foreach(var a in someInts)
        Console.WriteLine(a);
}

orderby子句

    static void Main(){
        var students = new []
        {
            new {LName ="Jones",FName="Mary",Age =19,Major ="History"},
            new {LName="Fleming",FName="Carol",Age=20,Major="CompSci"},
            new{LName ="Fleming",FName = "Carol",Age =21,Major ="History"}
};
    var query = from student in students
                orderby student.Age
                select student;
    foreach(var s in query)
    {
        Console.WriteLine("{0},{1}:{2}-{3}",s.LName,s.FName,s.Age,s.Major);
    }
}

标准查询运算符

标准查询运算符由一系列API方法组成,它能让我们查询任何.NET数组或集合。有关标准查询运算符的重要特性:

class Program
{
    static int[] numbers = new int[]{2,4,6};
    static void Main()
    {
        int total = numbers.Sum();
        int howMany= numbers.Count();
        Console.WriteLine("Total:{0},Count:{1}",total,howMany);
    }
}

共有47个标准查询运算符,可用来操作一个或多个序列。序列是指实现了Ienumerable<>接口的类,包括List<>、Dictionary<>、Stack<>、Array等。标准查询运算符可以帮助我们以非常强大的方式才查询和操作这些类型的对象。

查询表达式和标准查询运算符

查询表达式和方法语法这两种表达式也可以组合。

static void Main()
{
    var numbers = new int[]{2,6,4,8,10};
    int howMany= (from n in numbers 
                    where n <7 
                    select n).Count();
    Console.WriteLine("Count:{0}",howMany);
}

标准查询运算符

运算符名 描述
Where 根据给定的谓词对序列进行过滤
Select 指定要包含一个对象或对象的一部分
SelectMany 一种查询类型,返回集合的集合。该方法将这些结果合并为一个单独的集合
Take 接受一个输入参数count,返回序列中前count个对象
Skip 接受一个输入参数count,返回序列中的前count个对象
TakeWhile 接受一个谓词,开始迭代该序列,只要谓词对当前项的计算结果为true,就选择该项。在谓词返回第一个false的时候,该项和其余项都被丢弃
SkipWhile 接受一个谓词,开始迭代该序列,只要谓词对当前项的计算结果为true,就跳过该项。在谓词返回第一个false的时候,该项和其余项都会被选择
Join 对两个序列执行内联结,第一个序列中的各个元素都与第二个序列中的元素集合相关联
GroupJoin 可以产生层次结果的联结,第一个序列中的各个元素都与第二个序列中的元素集合相关联
Concat 连接两个序列
OrderBy/ThenBy 根据一个或多个键对序列中的元素排序
Reverse 反转序列中的元素
GroupBy 分组序列中的元素
Distinct 去除序列中的重复项
Union 返回两个序列的并集
Intersect 返回两个序列的交集
Except 操作两个序列。返回的是第一个序列中不重复的元素减去同样位于第二个序列中的元素
AsEnumerable 将序列作为IEnumerable返回
ToArray 将序列作为数组返回
ToList 将序列作为List返回
ToDictionary 将序列作为Dictionary
ToLookup 将序列作为LookUp
OfType 所返回的序列中的元素是指定的类型
Cast 将序列中所有的元素强制转换为给定的类型
SequenceEqual 返回一个布尔值,指定两个序列是否相等
First 返回序列中的第一个与谓词匹配的元素。如果没有元素与谓词匹配,就抛出InvalidOperation-Exception
FirstOrDefault 返回序列中的第一个与谓词匹配的元素。如果没有给出为,方法放回序列的第一个元素。如果没有元素与谓词匹配,就使用该类型的默认值
Last 返回序列中的最后一个与谓词匹配的元素。如果没有元素与谓词匹配,就抛出InvalidOperation-Exception
LastOrDefault 返回序列中最后一个与谓词匹配的元素。如果没有元素与谓词匹配,就返回默认值
Single 返回序列中与谓词匹配的单个元素。如果没有元素匹配,或多于一个元素匹配,就抛出异常
SingleOrDefault 返回序列中与谓词匹配的单个元素。如果没有元素匹配,或多于一个元素匹配,就返回默认值
ElementAt 给定一个参数n,返回序列中的第n+1个元素
ElementAtOrDefault 给定一个参数n,返回序列中的第n+1个元素。如果索引超出范围,就返回默认值
DefaultIfEmpty 提供一个在序列为空(empty)时的默认值
Range 给定一个start整型和count整型,该方法返回的序列包含count个整型,其中第一个元素的值为start,之后每个后续元素都比前一个大1
Repeat 给定一个T类型的element和一个count整数,该方法返回的序列具有count个element副本
Empty 返回给定类型T的空序列
Any 返回一个布尔值,指明序列中是否存在满足谓词的元素
All 返回一个布尔值,指明序列中的全部元素是否都满足谓词
Contains 返回一个布尔值,指明序列中是否包含给定的元素
Count 返回序列中元素的个数(int)。它的重载可以接受一个谓词,返回满足谓词的个数
LongCount 返回序列中元素的个数(long)。他的重载可以接受一个谓词,返回满足谓词的元素个数
Sum 返回序列中的值的总和
Min 返回序列中最小的值
Max 返回序列中最大的值
Average 返回序列中的平均值
Aggregate 连续对序列中的各个元素应用给定的函数

方法语法中使用委托

class Program
{
    static bool IsOdd(int x) //委托对象使用的方法
    {
        return x%2==1; //如果x是奇数,返回true
    }
    static void Main()
    {
        int[] intArray = new int[]{3,4,5,6,7,9};
        Func<int,bool>myDel = new Func<int,bool>(IsOdd);//委托对象
        var countOdd = intArray.Count(myDel);
        Console.WriteLine("Count of odd numbers:{0}",countOdd);
    }
}

自己的实践

class Program
{
    static bool IsOdd(string x)
    {
        return x.Length>4 ;
    }
    static void Main(string[] args)
    {
        string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay","Jay"};
        string[] fimally = {  "Mary", "Jay","Jay", "Tom", "Dick", "Harry"};
        // 编译器将会从Lambda表达式 n => n.Length推断出TResult为int类型
        Func<string, bool> myDel = new Func<string, bool>(IsOdd);//委托对象
        List pets = new List() { new pet(){Age = 1, Sex = "公"}, new pet(){Age = 2, Sex = "母"} };
        List pett= pets.Where(n => n.Age == 1).ToList();
        foreach (pet p in pett)
        {
            Console.WriteLine("年龄是:" + p.Age + ";性别是:" + p.Sex);
        }
    }
}
class pet
{
        public int Age;
        public string Sex;
}

你可能感兴趣的:(C#,Linq,匿名类型)