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<pet> pets = new List<pet>() { new pet(){Age = 1, Sex = "公"}, new pet(){Age = 2, Sex = "母"} };
        List<pet> pett= pets.Where<pet>(n => n.Age == 1).ToList();
        foreach (pet p in pett)
        {
            Console.WriteLine("年龄是:" + p.Age + ";性别是:" + p.Sex);
        }
    }
}
class pet
{
        public int Age;
        public string Sex;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值