C# - Linq (待更新)


C# - Linq(读作“link”)

什么是linq

  • “领克”,Language-Integrated Query,语言集成查询。
  • 对内存中数据、关系数据和XML数据执行的查询进行检查。

命令式 vs 声明式

  • 命令式是过程导向的,而声明式则是结果导向的。
  • 声明式 —— 对于sql,我们关心的是What,获取什么数据。
  • 命令式 —— 而对于面向对象语言,我们更关心How,如何获取数据。
  • 命令式适合处理对象关系和逻辑过程。
  • 而声明式更适合处理数据关系。

实例

using System.Linq;
using System.IO;
using System;
using System.Collections;
using System.Collections.Generic;

namespace _51Linq
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string path = @"c:\windows";
            ShowLargestFiles(path);

            Console.WriteLine("*****************");
            ShowLargestFilesWithLinq(path);

            Console.Read();
        }

        private static void ShowLargestFilesWithLinq(string path)
        {
            //var query = from file in new DirectoryInfo(path).GetFiles()
            //            orderby file.Length descending
            //            select file;

            var query = new DirectoryInfo(path).GetFiles()
                        .OrderByDescending(f => f.Length).Take(5);

            foreach (var f in query) {
                Console.WriteLine($"{f.Name,-20} : {f.Length,10:N}");
            }
                      
        }

        private static void ShowLargestFiles(string path)
        {
            DirectoryInfo directory = new DirectoryInfo(path);
            FileInfo[] files = directory.GetFiles();
            Array.Sort(files,new FileInfoComparer());


            for (int i = 0; i < 5; i++)
            {
                var f = files[i];
                Console.WriteLine($"{f.Name,-20} : {f.Length,10:N}");
            }
        }
    }

    internal class FileInfoComparer : IComparer<FileInfo>
    {
        public int Compare(FileInfo x, FileInfo y)
        {
            return y.Length.CompareTo(x.Length);
        }
    }
}

lambda表达式

案例 —— 有一个客户列表customers

匿名方法delegate —— 内联方法 inline

lambda表达式

实例 —— lambda表达式 —— 获取文件名字以b开头的

//接上-----------------------        

private static void ShowLargestFilesWithLinq(string path)
        {
            //var query = from file in new DirectoryInfo(path).GetFiles()
            //            orderby file.Length descending
            //            select file;

            var query = new DirectoryInfo(path).GetFiles()
                        .OrderByDescending(f => f.Length)
                        //lambda表达式
                //获取文件名字以b开头的
                        .Where(f => f.Name.StartsWith("b"))
                        .Take(5);

            foreach (var f in query) {
                Console.WriteLine($"{f.Name,-20} : {f.Length,10:N}");
            }
                      
        }

//接下-----------------------     

linq查询语法

案例 —— 获取名字以A开头的所有客户

实例

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            var customers = new List<Customer>
            {
                new Customer(1, "Alex", "广州"),
                new Customer(2, "Scott", "北京"),
                new Customer(3, "Chris", "上海"),
                new Customer(4, "Anna", "广州"),
                new Customer(5, "Angie", "深圳"),
                new Customer(6, "Bob", "武汉"),
                new Customer(7, "Tony", "深圳")
            };

            //var query = from c in customers
            //            where c.Address == "广州"
            //            orderby c.Name
            //            select c.Name;

            var query = customers
                .Where(c => c.Address == "广州")
                .OrderBy(c => c.Name);
                //.Select(c => c);

            foreach(var c in query)
            {
                Console.WriteLine($"客户:{c.Id}, {c.Name}, {c.Address}");
            }


            Console.Read();
        }
    }
    public class Customer
    {
        public Customer(int id, string name, string address)
        {
            Id = id;
            Name = name;
            Address = address;
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
    }
}

从csv中读取数据

实例

fuel.csv

修改该csv的属性

新建类 —— car.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    public class Car
    {
        public string Year { get; set; }
        public string Manufacturer { get; set; }
        public string Model { get; set; }
        public double Displacement { get; set; }
        public int CylindersCount { get; set; }
        public int City { get; set; }
        public int Highway { get; set; }
        public int Combined { get; set; }
    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Car> cars = ProcessCars("fuel.csv"); 

            Console.Read();
        }

        private static List<Car> ProcessCars(string v)
        {
            var result = File.ReadAllLines(v)
                .Skip(1)
                .Where(l => l.Length > 1)
                .Select(line =>
                {
                    var columns = line.Split(",");
                    return new Car
                    {
                        Year = columns[0],
                        Manufacturer = columns[1],
                        Model = columns[2],
                        Displacement = double.Parse(columns[3]),
                        CylindersCount = int.Parse(columns[4]),
                        City = int.Parse(columns[5]),
                        Highway = int.Parse(columns[6]),
                        Combined = int.Parse(columns[7])
                    };
                });

            return result.ToList();
        }
    }
   
}

排序与过滤

实例

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Car> cars = ProcessCars("fuel.csv");

            //排序与过滤
/*            var query = cars.OrderByDescending(c =>c.Combined)
                //ThenByDescending 降序
                .ThenByDescending(c => c.Model);*/

            var query = (from car in cars 
                        where car.Manufacturer == "BMW" && car.Year == "2016"
                        orderby car.Combined descending,car.Model descending
                        select car)
                        //.First()
                        .FirstOrDefault();

/*            foreach (var c in query) {*/
                Console.WriteLine($"{query.Model} {query.Combined}");
/*            }*/

            Console.Read();
        }

        private static List<Car> ProcessCars(string v)
        {
            var result = File.ReadAllLines(v)
                .Skip(1)
                .Where(l => l.Length > 1)
                .Select(line =>
                {
                    var columns = line.Split(",");
                    return new Car
                    {
                        Year = columns[0],
                        Manufacturer = columns[1],
                        Model = columns[2],
                        Displacement = double.Parse(columns[3]),
                        CylindersCount = int.Parse(columns[4]),
                        City = int.Parse(columns[5]),
                        Highway = int.Parse(columns[6]),
                        Combined = int.Parse(columns[7])
                    };
                });

            return result.ToList();
        }
    }
   
}

数据量化Any、All、Contains

Any

            //Any()
            var query2 = cars.Any(c => c.Manufacturer == "Volkswagen");
            Console.WriteLine(query2);
            if (query2)
            {
                Console.WriteLine("有大众");
            }
            else
            {
                Console.WriteLine("没有大众");
            }

            var isCarsEmpty = cars.Any();

All

            //all
            //输出FALSE,没有大众
            var query3 = cars.All(c => c.Manufacturer == "Volkswagen");
            Console.WriteLine(query3);
            if (query3)
            {
                Console.WriteLine("有大众");
            }
            else
            {
                Console.WriteLine("没有大众");
            }

            var isCarsEmpty2 = cars.Any();

Contains

            // contains
            var isReal = cars.Contains(query);
            //输出True
            Console.WriteLine(isReal);

数据投影与Select Many

实例

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Car> cars = ProcessCars("fuel.csv");
            //var query = cars
            //    .OrderByDescending(c => c.Combined)
            //    .ThenByDescending(c => c.Model);

            var query = (from car in cars
                         where car.Manufacturer == "BMW" && car.Year == "2016"
                         orderby car.Combined descending, car.Model descending
                         select new {
                             Model = car.Model,
                             Combined = car.Combined
                         })
                        //.First()
                        .FirstOrDefault()
                        ;

            //foreach (var c in query)
            //{
            Console.WriteLine($"{query.Model} {query.Combined}");
            //}

            // Any()
            var query2 = cars.All(c => c.Manufacturer == "Volkswagen");
            Console.WriteLine(query2);
            if (query2)
            {
                Console.WriteLine("有大众");
            }
            else
            {
                Console.WriteLine("没有大众");
            }

            var isCarsEmpty = cars.Any();

            // contains
            //var isReal = cars.Contains(query);

            // all
            var query3 = cars.SelectMany(c => c.Model);
            foreach(var c in query3)
            {
                Console.WriteLine(c);
            }


            Console.Read();
        }

        private static List<Car> ProcessCars(string v)
        {
            var result = File.ReadAllLines(v)
                .Skip(1)
                .Where(l => l.Length > 1)
                .ToCar()
                //.Select(line =>
                //{
                //    var columns = line.Split(",");
                //    return new Car
                //    {
                //        Year = columns[0],
                //        Manufacturer = columns[1],
                //        Model = columns[2],
                //        Displacement = double.Parse(columns[3]),
                //        CylindersCount = int.Parse(columns[4]),
                //        City = int.Parse(columns[5]),
                //        Highway = int.Parse(columns[6]),
                //        Combined = int.Parse(columns[7])
                //    };
                //})
                ;

            return result.ToList();
        }
    }

    public static class CarExtensions 
    {
        public static IEnumerable<Car> ToCar(this IEnumerable<string> source)
        {
            foreach(var line in source)
            {
                var columns = line.Split(",");
                yield return new Car
                {
                    Year = columns[0],
                    Manufacturer = columns[1],
                    Model = columns[2],
                    Displacement = double.Parse(columns[3]),
                    CylindersCount = int.Parse(columns[4]),
                    City = int.Parse(columns[5]),
                    Highway = int.Parse(columns[6]),
                    Combined = int.Parse(columns[7])
                };
            }
        }
    }
   
}

数据连接join

数据分组group

数据分组连接group join

数据聚合

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - C# - Linq (待更新)


三二一的一的二