1. 程式人生 > 其它 >Linq之SelectMany(from..from..複合from子句)

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;