• Linq之SelectMany(from..from..复合from子句)


    1、 Linq之SelectMany(from..from..复合from子句)

    如果需要根据对象的一个成员进行筛选,而该成员本身一个集合,就可以使用复合的from子句

    代码如下:

    public class ms
    {
        void Main()
        {
            List<Person> personList = new List<Person>
            {
                new Person
                {
                    Name = "P1", Age = 18, Gender = "Male",
                    Dogs = new Dog[]
                    {
                        new Dog { Name = "D1" },
                        new Dog { Name = "D2" }
                    }
                },
                new Person
                {
                    Name = "P2", Age = 19, Gender = "Male",
                    Dogs = new Dog[]
                    {
                    new Dog { Name = "D3" }
                    }
                },
                new Person
                {
                    Name = "P3", Age = 17,Gender = "Female",
                    Dogs = new Dog[]
                    {
                        new Dog { Name = "D4" },
                        new Dog { Name = "D5" },
                        new Dog { Name = "D6" }
                    }
                }
            };
            Console.WriteLine("********第⼀种⽤法*************************************");
            //官⽅释义:将序列的每个元素投影到 IEnumerable<TResult> 并将结果序列合并为⼀个序列。
            //public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector);
            var results1 = personList.SelectMany(p => p.Dogs);
            // 其等价的LINQ语句为:
            //var results1 = from p in personList
            // from d in p.Dogs
            // select d;
            foreach (var dog in results1)
            {
                Console.WriteLine(dog.Name);
            }
            Console.WriteLine();
            Console.WriteLine("********第⼆种⽤法*************************************");
            //官⽅释义:将序列的每个元素投影到 IEnumerable<TResult>,并将结果序列合并为⼀个序列。每个源元素的索引⽤于该元素的投影表。
            //public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector);
            var results2 = personList.SelectMany((p, i) => p.Dogs.Select(d => new
            {
                Name = $"{i},{d.Name}"
            }));
            foreach (var dog in results2)
            {
                Console.WriteLine(dog.Name);
            }
            Console.WriteLine();
            Console.WriteLine("********第三种⽤法*************************************");
            //官⽅释义:将序列的每个元素投影到 IEnumerable<TCollection>,并将结果序列合并为⼀个序列,并对其中每个元素调⽤结果选择器函数。
            //public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection
            var results3 = personList.SelectMany(p => p.Dogs, (p, d) => new { PersonName = p.Name, DogName = d.Name });
            // 其等价的LINQ语句为:
            //var results3 = from p in personList
            // from d in p.Dogs
            // select new { PersonName = p.Name, DogName = d.Name };
            foreach (var result in results3)
            {
                Console.WriteLine($"{result.PersonName},{result.DogName}");
            }
            Console.WriteLine();
            Console.WriteLine("********第四种⽤法*************************************");
            //官⽅释义:将序列的每个元素投影到 IEnumerable<TCollection>,并将结果序列合并为⼀个序列,并对其中每个元素调⽤结果选择器函数。每个源元素的索引⽤于该元素的中间投影表。
            //public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection
            var results4 = personList.SelectMany((p, i) => p.Dogs.Select(d => new
            {
                Name = $"{i},{d.Name}"
            }),(p, d) => new { PersonName = p.Name, DogName = d.Name });
            foreach (var result in results4)
            {
                Console.WriteLine($"{result.PersonName},{result.DogName}");
            }
            Console.WriteLine();
        }
        class Person
        {
            public string Name { set; get; }
            public int Age { set; get; }
            public string Gender { set; get; }
            public Dog[] Dogs { set; get; }
        }
        public class Dog
        {
            public string Name { set; get; }
        }
    }

    结果:

    ********第⼀种⽤法*************************************
    D1
    D2
    D3
    D4
    D5
    D6
    ********第⼆种⽤法*************************************
    0,D1
    0,D2
    1,D3
    2,D4
    2,D5
    2,D6
    ********第三种⽤法*************************************
    P1,D1
    P1,D2
    P2,D3
    P3,D4
    P3,D5
    P3,D6
    ********第四种⽤法*************************************
    P1,0,D1
    P1,0,D2
    P2,1,D3
    P3,2,D4
    P3,2,D5
    P3,2,D6

    2、复合from⼦句与join⼦句 

    复合from⼦句实际上就是联接查询,⼤部分复合from⼦句(并不是所有,如cross join)的Linq完全可以⽤join⼦句的Linq来重写,两者⽣成的Sql也相同,推荐使⽤join
    Linq,这种写法与Sql更接近,更易读。

    var query1 = from o in dbContext.Orders
    from od in o.Order_Details
    select o;
    var query2 = from o in dbContext.Orders
                 join od in dbContext.Order_Details
                 on o.OrderID equals od.OrderID
    select o;
  • 相关阅读:
    本地Springboot项目打包成docker镜像并上传到云仓库的全流程
    vue 组件开发到发布到npm全流程
    Python创建文件
    Ngrinder脚本开发各细节锦集(groovy)
    Ngrinder多接口的混合场景压测比例设定方案
    Pycahrm出现推送失败的处理方案,出现Push failed: Failed with error: Authentication failed for 'https://gitee.com/fxcity/Temporary_Test.git/'
    接口测试提取csrf_token和session
    Postman提取html返回值
    HttpRunnerManager自动化测试安装部署(CentOS)
    【转载】centos下搭建RabbitMQ
  • 原文地址:https://www.cnblogs.com/youmingkuang/p/16257165.html
Copyright © 2020-2023  润新知