linq查询操作包括三个部分:

获取数据源 创建查询 执行查询

lambda表达式:

Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。

所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to”。该 Lambda 运算符的左边是输入参数(如果有),右边包含表达式或语句块。Lambda 表达式 x => x * x 读作“x goes to x times x”。可以将此表达式分配给委托类型

 static void Main()

 {

          del myDelegate = x => x * x;

          int j = myDelegate(5); //j = 25

          Console.WriteLine(j);

 }

     delegate int del(int i);

只有在 Lambda 有一个输入参数时,括号才是可选的;否则括号是必需的。无参也需要括号,两个或更多输入参数由括在括号中的逗号分隔:

     (x, y) => x == y

Lambda 的一般规则如下:

Lambda 包含的参数数量必须与委托类型包含的参数数量相同。

Lambda 中的每个输入参数必须都能够隐式转换为其对应的委托参数。

Lambda 的返回值(如果有)必须能够隐式转换为委托的返回类型。

查询语法与方法语法:

string[] Devices= {"电视" ,"电冰箱","洗衣机","电话","微波炉"};

查询语法

      var SelectDevices = from device in Devices

                                where device.StartsWith("电")

                                select device;

方法语法

      var SelectDevices =Devices .Where ( device => device.StartsWith("电"))

  

            foreach (string dev in SelectDevices)

            {

                Console.WriteLine("带电的设备:{0}",dev);

 1.投影操作符           }

(1)Select :对单个序列或集合中的值进行投影。

(2)SelectMany:将序列的每个元素投影到 IEnumerable<(Of <(T>)>) 并将结果序列合并为一个序列。

例子:

class Devices

    {

        public string Name

        { get; set; }

        public List Price

        { get; set; }

    }

     static void Main()

        {

            Devices[] DeviceGroup = { new Devices { Name = "电视", Price =new List{ 3000,2000} }, new Devices { Name = "电冰箱", Price =new List { 4000,5000 }}, new Devices { Name = "洗衣机", Price =new List { 1500,1000 }} };

            var devices = DeviceGroup.SelectMany(device => device.Price  );

            foreach (var  v in devices)

            {

                Console.WriteLine(v);

            }

        }

 2.限制操作符

(1)Where:对单个序列或集合中的值进行投影。

 3.排序操作符:按照升序和降序的方式对结果进行排序的功能。

(1)OrderBy:将序列中的返回值按照升序的顺序进行排列。

(2)OrderByDescending:将序列中的返回值按照降序的顺序进行排列。

(3)ThenBy:排序依据的次关键字。 

(4)ThenByDescending:倒排序依据的次关键字。

(5)Reverse:反转序列。

例子:

Devices[] DeviceGroup = { new Devices { Name = "电视", Price = 10000 }, new Devices { Name = "电话", Price = 240 }, new Devices { Name = "电视", Price = 3000 } };

            var devices = from device in DeviceGroup

                          orderby device.Name,device .Price descending

                          select device;

           // var devices = DeviceGroup.AsQueryable().OrderBy(device => device.Name).ThenByDescending(device => device.Price);

            foreach (var dev in devices)

            {

                Console.WriteLine("品名:{0},价格:{1}",dev.Name,dev.Price );

            }

 4.联接操作符:将两个或多个数据源对象进行关联或联合。

(1)Join:按照一定的条件,将两个数据源关联起来。

(2)GroupJoin:将主数据源中的每一个值或元素与次数据源中相应的值联接起来。

例子:

static void Main()

        {

           List A_Class = new List(); //声名一个A班,来存放学员

            A_Class.Add(new StudentMessage { ID = 1001, Name = "张三", Sex = true, Age = 20 }); //添加学员

            A_Class.Add(new StudentMessage { ID = 1002, Name = "李四", Sex = false, Age = 21 });//添加学员

            List A_ScortSheet = new List(); //声名一个成绩表

            A_ScortSheet.Add(new ChineaseScort { ID = 1001, Scort = 100f, Subject = "语文" }); //添加语文成绩

            A_ScortSheet.Add(new ChineaseScort { ID = 1002, Scort = 80f, Subject = "语文" });  //添加语文成绩

            A_ScortSheet.Add(new MathsScort { ID = 1001, Scort = 90f, Subject = "数学" });     //添加数学成绩

            A_ScortSheet.Add(new MathsScort { ID = 1002, Scort = 60f, Subject = "数学" });     //添加数学成绩

            var messages = A_Class.GroupJoin(A_ScortSheet, mes => mes.ID, sco => sco.ID, (mess, scor) => new { Mess = mess.ID, Mename = mess.Name, Scor = scor.Select(Scor => Scor) });

            foreach (var scort in messages)

            {

                Console.WriteLine("学号:{0,4} 姓名:{1}", scort.Mess, scort.Mename);

                foreach (var sc in scort.Scor)

                {

                    Console.WriteLine("   {0}:{1}分", sc.Subject, sc.Scort);

                }

            }

数据源1.GroupJoin(数据源2,变量1=>数据源1.关联字段,变量2=>数据源码2.关联字段,(数据源1数据变量,数据源2数据列表变量)=>new{变量a=数据源1.字段1,变量b=数据源1.字段2,变量c=数据源2列表变量.Select(变量c=变量c)})

 5.分组操作符:按照一定的值将序列中的值或元素进行分组。

(1)GroupBy

例子:

static void Main()

        {

            Student[] students = new Student[] {

             new Student{ClassName="A", Name="张三"},

             new Student{ClassName ="B", Name ="李四"},

             new Student{ClassName ="A" ,Name ="王五"},

             new Student {ClassName ="B", Name ="赵六"},

             new Student{ClassName ="B" ,Name ="钱七"},

             new Student {ClassName ="B", Name ="孙八"}

            };

            var stus = (from stu in students

                        select stu).GroupBy(st => st.ClassName);

            //var stus = students.GroupBy(st => st.ClassName);

            foreach (var v in stus)

            {

                Console.WriteLine("{0}班学生:", v.Key);

                foreach (var va in v)

                {

                    Console.WriteLine("  姓名:{0}", va.Name);

                }

            }

        }  

 6.合并操作符:将两个对象合并在一起。

(1)Concat:

var Cont = Citys.Select(city => city).Concat(Mobiles.Select(mobil => mobil));

 7.聚合操作符:在一系列值上执行特定的运算,并返回单个值。

(1)Aggregate:从序列或集合中收集值。

(2)Average:求一个数值序列的平均值。

(3)Count:求一个数值序列的个数。(LongCount用法相同)。

(4)Sum:求一个数值序列的和。

例子:

string[] citys = {"北京","上海","东京"};

            string newcity = citys.Aggregate((cityname,next)=>next+"-"+cityname);

            Console.WriteLine(newcity);

//var quer = list.Count(lis=>lis.Chinese >80);

 8.集合操作符:对元素的集合或序列集合进行操作,并返回一个集合。

(1)Distinct:删除集合中重复的值,并返回该项集合中互不相同的元素。

(2)Union:将两个集合或序列合并后返回不同的元素。

(3)Intersect:返回两个集合的交集。

(4)Except:返回序列一中序列二没有的值。

 9.生成操作符:从现有的序列中创建新的序列。

(1)Empty:指定类型的空集。

 var s= Enumerable.Empty();

           Console.WriteLine(s.Count ());

(2)Range:创建一个包含数字序列的集合。

 foreach (var num in Enumerable.Range(3, 9))

            {

                Console.WriteLine(num);

            }

(3)Repeat:将值重复一定的次数。

 foreach (var num in Enumerable.Repeat(“*****”,9))

            {            

                Console.WriteLine(num);

            }

 10.转换操作符:将输入对象类型转变为序列的动作。

(1)AsEnumerable:

(2)Cast:将序列转换成指定的类型。

(3)OfType:过滤序列中的某种类型。

(4)ToArray:从IEnumerable序列创建一个数组。

(5)ToDictionary:从IEnumerable序列创建一个Dictionary序列。

(6)ToList:从IEnumerable序列创建一个List序列。

(7)ToLookup:从IEnumerable序列创建一个 Lookup序列。Lookup是主键的集合,其中主键对应着一个或多个值。

class OrderTable

    {

        public int OrderNum

        { get; set; }

        public double Amount

        { get; set; }

    }  

            List list = new List();

            list.Add(new OrderTable { OrderNum = 1001, Amount = 1234.5 });

            list.Add(new OrderTable { OrderNum = 1002, Amount = 2340 });

            list.Add(new OrderTable { OrderNum = 1001, Amount = 3000 });

            var lis = list.ToLookup(num => num.OrderNum, num => num.Amount);

            foreach (var item in lis)

            {

                Console.WriteLine("订单号:{0}",item.Key );

                foreach (var v in item)

                {

                    Console.WriteLine("  {0}元",v);

                }

            }

 11.元素操作符:从一个序列返回单个特定的元素。

(1)DefaultIfEmpty:将空集合替换为包含默认的单个值的集合。

(2)ElementAt:返回集合中给定索引的元素。

(3)ElementAtOrDefault:是将ElementAt和DefaultIfEmpty。

(4)First:返回集合中的第一个元素(Last返回最后一个)。

(5)FirstOrDefault:返回集合中的第一个元素,如果不存在,返回默认值(LastOrDefault返回最后一个,如果不存在,返回默认值)。

(6)Single:从一个序列中返回单个元素,或唯一满足某一特定条件的元素。(LastOrDefault返回最后一个,如果不存在,返回默认值)。

(7)SingleOrDefault:从一个序列中返回单个元素,或唯一满足某一特定条件的元素。如果存在多条记录,抛出异常。

var value = list.Where (li=>li.OrderNum ==1002).Select(lis=>lis.OrderNum).Single();          

 12.相等操作符:比较两个序列的元素是否相同。

(1)SequenceEqual

 int[] Arr1 = { 1, 2, 3 };

            int[] Arr2 = { 1, 2, 3 };

            Console.WriteLine(Arr1.SequenceEqual(Arr2))

13.量词操作符:是否存在部分或全部元素符合某个特定条件。

(1)All:判定在集合中是否所有的值都满足特定的条件。

            int[] Arr1 = { 1, 1, 1 };

   Console.WriteLine(Arr1.All (arr=>arr==1));

(2)Any:判定在集合中是否有的值满足特定的条件。

            int[] Arr1 = { 1, 2, 3 };

            Console.WriteLine(Arr1.Any (arr=>arr==1));

(3)Contains:判定在集合中是否包含某个值。

            int[] Arr1 = { 1, 2, 3 };

            Console.WriteLine(Arr1.Contains(4));

14.分割操作符:将一个序列分割成两个或多个序列。

(1)Skip:跳过序列的前n个元素后返回所有的元素。

           

    int[] Arr = { 1, 2, 3,4,5,6 };

            foreach (int i in Arr.Skip(2))

            {

                Console.WriteLine(i);

            }

(2)SkipWhile:跳过不满足条件的元素,返回余下元素的序列。

            需要注意的是,这种跳出过必需排序后才能全部跳过满足条件的元素。

    int[] Arr = { 1, 12, 3,4,15,6};

            foreach (int i in Arr.OrderBy (nu=>nu).SkipWhile(arr=>arr<=10))

            {

                Console.WriteLine(i);

            }

(3)Take:返回序列的从开始到参数指定位置的元素。

 int[] Arr = { 1, 2, 3,4,5,6 };

            foreach (int i in Arr.Take(2))

            {

                Console.WriteLine(i);

            }

(4)TakeWhile:返回满足条件的元素。

            需要注意的是,这种返回必需排序后才能进行操作。

     int[] Arr = { 1, 12, 3,4,15,6};

            foreach (int i in Arr.OrderBy (ar=>ar).TakeWhile(arr=>arr<12))

            {

                Console.WriteLine(i);

            }

总结:

查询语法就是 :from 表名 where 条件 select 所需要的列名

方法语法就是:表名.where(条件).select(所需要的列名)