常用LINQ关键字用法汇总

Posted lixiaobin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用LINQ关键字用法汇总相关的知识,希望对你有一定的参考价值。

背景

传统上,针对数据的查询都以简单的字符串表示,而没有编译时类型检查或 IntelliSense 支持。此外,还需要针对每种数据源学习一种不同的查询语言:SQL 数据库、XML 文档、各种 Web 服务等等。 LINQ 使查询成为 C# 中的一流语言构造。 可以使用语言关键字和熟悉的运算符针对强类型化对象集合编写查询。

注意事项

版本需求:.NET Framework 3.5 或更高版本

查询对象:SQL Server 数据库、XML 文档、ADO.NET 数据集以及支持 IEnumerable 或泛型 IEnumerable<T> 接口的任何对象集合

引用包:System.Linq

以下按照使用度排序介绍。

Where

用于过滤数据,减少IF分支语句。

例子:

            StringBuilder str = new StringBuilder();
            foreach (int item in list.Where(d => d % 2 == 0))
            {
                str.Append(item);
            }

老式IF用法:

            StringBuilder str = new StringBuilder();
            foreach (int item in list)
            {
                if (item % 2 == 0)
                {
                    str.Append(item);
                }
            }

Take

从数据源开始位置读取指定的元素个数用。

例子:

            var list = Enumerable.Range(1, 100000);

            foreach (int item in list.Take(10))
            {
                Console.WriteLine(item.ToString());
            }

Select

抽取数据源中类型的指定元素组建成新的类型。主要用于简化数据列或者转换数据类型,以及获取元素Index。

例子:

            var list = new List<Animal> {
                new Animal{ Name="hot dog",Sex=1,Age=10},
                new Animal{ Name="big dog",Sex=0,Age=11},
                new Animal{ Name="bin dog",Sex=0,Age=12},
                new Animal{ Name="baby dog",Sex=1,Age=13},
            };

            foreach (string item in list.Select(a => a.Name))
            {
                Console.WriteLine(item.ToString());
            }

            foreach (var item in list.Select(a => new { Name = a.Name, Length = a.Age * 2, Type = "S" }))
            {
                Console.WriteLine(item.ToString());
            }

            foreach (var item in list.Select((value, index) => new { Number = index, Name = value }))
            {
                Console.WriteLine(item.ToString());
            }

            foreach (string item in list.Select(a => a.Sex.ToString("D2")))
            {
                Console.WriteLine(item.ToString());
            }

            foreach (int item in list.Select(a => a.Age * 2))
            {
                Console.WriteLine(item.ToString());
            }

结果:

技术图片

SelectMany

将数据源降维抽取,减少For循环。类似Select,适合多重子集的数据源抽取数据。

例子:

            var parameters = new Parameter[]
              {
                new Parameter() { Name = "正一", Numbers = new int[] { 1, 2, 3 } },
                new Parameter() { Name = "清次", Numbers = new int[] { 1, 3, 5 } },
                new Parameter() { Name = "誠三", Numbers = new int[] { 2, 4, 6 } },
                new Parameter() { Name = "征史", Numbers = new int[] { 9, 8, 7 } },
              };

            StringBuilder str = new StringBuilder();
            var result = parameters.SelectMany(value => value.Numbers);
            foreach (int value in result)
            {
                str.Append($"{value},");
            }
            Console.WriteLine(str.ToString());

结果:

技术图片

如果使用Select就是如下写法:

            var parameters = new Parameter[]
              {
                new Parameter() { Name = "正一", Numbers = new int[] { 1, 2, 3 } },
                new Parameter() { Name = "清次", Numbers = new int[] { 1, 3, 5 } },
                new Parameter() { Name = "誠三", Numbers = new int[] { 2, 4, 6 } },
                new Parameter() { Name = "征史", Numbers = new int[] { 9, 8, 7 } },
              };

            var results = parameters.Select(value => value.Numbers);

            StringBuilder str = new StringBuilder();
            foreach (int[] values in results)
            {
                foreach (int number in values)
                {
                    str.Append($"{number},");
                }
            }
            Console.WriteLine(str.ToString());

结果:

技术图片

Distinct

去掉重复数据留下一个,一般用于基础数据类型。如果是类需要指定比较方法。

            int[] dataA = new int[] { 0, 1, 3, 3, 2 };
            List<float> dataB = new List<float>() { 1.5f, 1.5f, 1.5f, 1.5f };

            IEnumerable<int> dataA_D = dataA.Distinct();
            IEnumerable<float> dataB_D = dataB.Distinct();

            foreach (var d in dataA_D)
            {
                Console.WriteLine(d);
            }
            foreach (var d in dataB_D)
            {
                Console.WriteLine(d);
            }

技术图片

Any

用来判断列表是否为空,速度比Count()快。如果是类,可以指定判断条件。

            int[] numbersA = new int[] { };
            int[] numbersB = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var list = new List<Animal> {
                new Animal{ Name="hot dog",Sex=1},
                new Animal{ Name=null,Sex=0},
                new Animal{ Name="bin dog",Sex=0},
                new Animal{ Name="baby dog",Sex=1},
            };
            
            Console.WriteLine(numbersA.Any());
            Console.WriteLine(numbersB.Any());
            Console.WriteLine(list.Any(a => a.Name == null));

技术图片

Join

两组数据结合。也可以用来根据某个表排序数据。

public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>( this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector );

参数说明:

outer:结合的数据列表A

inner:结合的数据列表B

outerKeySelector:列表A的主键字段

innerKeySelector:列表B的主键字段

resultSelector:返回结果定义。(匿名类居多)

            PersonData[] persons = new PersonData[]
            {
            new PersonData() { Name = "正一郎", ItemID = 0 },
            new PersonData() { Name = "清次郎", ItemID = 1 },
            new PersonData() { Name = "誠三郎", ItemID = 2 },
            new PersonData() { Name = "征史郎", ItemID = 0 },
            };

            ItemData[] items = new ItemData[]
            {
            new ItemData() { ID = 0, Name = "" },
            new ItemData() { ID = 1, Name = "権力" },
            };

            var joinList = persons.Join(
                                    items,
                                    person => person.ItemID,
                                    item => item.ID,
                                    (person, item) => new { PersonName = person.Name, ItemName = item.Name });

            foreach (var item in joinList)
            {
                Console.WriteLine($"Person:{item.PersonName}, Item:{item.ItemName}");
            }

技术图片

Except

求两个数据列表的差分集合用。

            int[] numbersA = new int[] { 1, 2, 3, 4, 5 };
            int[] numbersB = new int[] { 8, 6, 4, 2, 0 };

            IEnumerable<int> results = numbersA.Except(numbersB);
            foreach (var d in results)
            {
                Console.WriteLine(d);
            }

技术图片

自定义比较条件的情况

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

        public override string ToString()
        {
            return string.Format("ID:{0}, Name:{1}", ID, Name);
        }
    }
    class ParameterComparer : IEqualityComparer<Parameter>
    {
        public bool Equals(Parameter i_lhs, Parameter i_rhs)
        {
            if (i_lhs.ID == i_rhs.ID &&
                i_lhs.Name == i_rhs.Name)
            {
                return true;
            }
            return false;
        }

        public int GetHashCode(Parameter i_obj)
        {
            return i_obj.ID ^ i_obj.Name.GetHashCode();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Parameter[] dataA = new Parameter[]
            {
                new Parameter() { ID = 0, Name = "正一郎" },
                new Parameter() { ID = 5, Name = "清次郎" },
                new Parameter() { ID = 3, Name = "誠三郎" },
                new Parameter() { ID = 9, Name = "征史郎" },
            };
            Parameter[] dataB = new Parameter[]
            {
            new Parameter() { ID = 5, Name = "清次郎" },
            new Parameter() { ID = 3, Name = "誠三郎" },
            new Parameter() { ID = 2, Name = "征史郎" },
            };

            ParameterComparer compare = new ParameterComparer();
            IEnumerable<Parameter> results = dataA.Except(dataB, compare);

            foreach (var item in results)
            {
                Console.WriteLine(item.ToString());
            }
            Console.ReadKey();
        }
    }

技术图片

Range

指定开始位置,指定个数的连续列表做成。

            IEnumerable<int> intSequenceA = Enumerable.Range(1, 5);
            IEnumerable<int> intSequenceB = Enumerable.Range(-1, 3);
            IEnumerable<int> intSequenceC = Enumerable.Range(100, 4);

            foreach (var d in intSequenceA)
            {
                Console.WriteLine(d);
            }
            Console.WriteLine("=========");
            foreach (var d in intSequenceB)
            {
                Console.WriteLine(d);
            }
            Console.WriteLine("=========");
            foreach (var d in intSequenceC)
            {
                Console.WriteLine(d);
            }

技术图片

备注:https://www.urablog.xyz/entry/2018/07/10/070000

以上是关于常用LINQ关键字用法汇总的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式常用用法汇总

linq to js 用法

MySQL常用命令汇总及用法

常用正则用法汇总

shell中常用括号用法汇总 linux课程学习

新手程序员进阶必学,Python常用模块及用法汇总(内容较干建议收藏)