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


    [C#] LINQ之SelectMany - cnxy - 博客园 (cnblogs.com)

    LINQ TO SQL中的selectMany - min.jiang - 博客园 (cnblogs.com)

    Enumerable.SelectMany 方法 (System.Linq) | Microsoft Docs

    from 子句 - C# 参考 | Microsoft Docs

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

    代码如下

    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, TResult> resultSelector);
    
        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, TResult> resultSelector);
        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

    复合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;
  • 相关阅读:
    程序员需要的各种PDF格式电子书【附网盘免费下载资源地址】
    Web安全大揭秘
    tar 压缩解压命令详解
    django开发项目的部署nginx
    CentOS7安装mysql-python模块
    我的博客站点上线了
    2006
    centos7安装pip
    mysql删除匿名用户
    FilenameFilter 文件名过滤
  • 原文地址:https://www.cnblogs.com/springsnow/p/14994302.html
Copyright © 2020-2023  润新知