Linq是Language Integrated Query的简称,它是微软在.NET Framework 3.5里面新加入的特性,用以简化查询查询操作。本文主要介绍.NET(C#) 中Linq的Select和SelectMany操作符的使用及区别。

1、Select操作符

Select操作符对单个序列或集合中的值进行投影。所谓投影,比如有一个数据集,想用LINQ语法去操作数据集,会写一个LINQ的表达式,表达式会把数据集合中的数据简单的投影到一个变量中,并且可以通过这个变量去筛选数据。

例如,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{
   class Program
   {
        static void Main(string[] args)
        {
            //使用集合初始化器给集合赋值
            List<Employees> emp = new List<Employees> 
            { 
               new Employees(){Id=Guid.NewGuid(),Name="C",Sex=0,CompanyName="xx技术有限公司"},
               new Employees(){Id=Guid.NewGuid(),Name="Java",Sex=0,CompanyName="xx培训"},
               new Employees(){Id=Guid.NewGuid(),Name="Python",Sex=0,CompanyName="xx集团"}
            };
            //查询语法:不能省略最后的select
            var query = (from p in emp where p.Name.StartsWith("C") select p).FirstOrDefault();
            //查询方法:设计到Lambda表达式,全部返回 可以省略最后的select 延迟加载
            var query1 = emp.Where(p => p.Name.StartsWith("C")).Select(e => new { e.Name,e.CompanyName});
            foreach (var item in query1)
            {
                Console.WriteLine(item.Name);
            }
            //查询方法
            var query2 = emp.Where(p => p.Name.StartsWith("C")).Select(p => p.CompanyName);
            foreach (var item in query2)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
    public class Employees
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public int Sex { get; set; }
        public string CompanyName { get; set; }
    }
}

2、SelectMany操作符

SelectMany操作符用于根据输入序列中的每一个元素,在输出序列中创建相应的零个或者多个元素,与Select操作符不同,Select操作符会根据输入序列中的每一个元素创建一个对应的输出序列元素,而SelectMany操作符可以创建多个。

例如,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            List<People> pList = new List<People>();
            People p1 = new People(1, "C", 21);
            People p2 = new People(1, "Java", 22);
            People p3 = new People(1, "Python", 23);
            pList.Add(p1);
            pList.Add(p2);
            pList.Add(p3);
            var newList = pList.SelectMany(p => p.Name);    //newList是一个包含所有p.Name的字符的集合IEnumerable<char>
            foreach (var item in newList)                   //Select是一个元素返回一个字符串,而SelectMany是一个元素返回多个字符            {
            {
                Console.Write(item);
            }
            Console.WriteLine();
            var items = pList.SelectMany((p, i) => i < 2 ? p.Name.ToArray() : new char[] { });  //前两个元素才转成字符输出
            foreach (var i in items)
            {
                Console.Write(i);
            }
            Console.ReadKey();
        }
    }
    public class People
    {
        public People(int id, string name, int age)
        {
            this.Id = id;
            this.Name = name;
            this.Age = age;
        }
        public int Id
        {
            get;
            set;
        }
        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
    }
}

3、Select与SelectMany的区别

Select()每一次遍历,输出的是T,然后将所有遍历后得到的T组合成一个IEnumerable<T>SelectMany()每遍历一次,输出的是IEnumerable<T>,然后合并成一个大的IEnumerable<T>

例如,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] text1 = { "C Java Python", "html css js", "SQL MySQL Oracle" };
            var tokens1 = text1.Select(s => s.Split(' '));
            Console.WriteLine(tokens1);
            //遍历需要两个foreach
            foreach (string[] line in tokens1)
                foreach (string token in line)
                    Console.WriteLine("{0}.", token);
            string[] text2 = { "C Java Python", "html css js", "SQL MySQL Oracle" };
            var tokens2 = text2.SelectMany(s => s.Split(' '));
            Console.WriteLine(tokens2);
            //遍历只需要一个foreach
            foreach (string token in tokens2)
                Console.WriteLine("{0}.", token);
            Console.ReadKey();
        }
    }
}

推荐文档