不太常使用到LINQ的SelectMany,每次使用到SelectMany都要回去翻網路文章或是微軟文件確認語法,乾脆簡單記錄在這裡一勞永逸,沒啥技術性請參考參考即可。
兩個資料類別的程式碼如下:
//部門 class OrmDepartment { public int iDepartment { get; set; } public string cDepartmentName { get; set; } public System.Collections.Generic.List<OrmEmployee> oEmployee { get; set; } } //員工 class OrmEmployee { public int iEmployee { get; set; } public string cEmployeeName { get; set; } }
主要使用方式如下:
static void Main(string[] args) { var oList = new System.Collections.Generic.List<OrmDepartment>() { new OrmDepartment() { iDepartment = 1, cDepartmentName = "行銷部", oEmployee = new System.Collections.Generic.List<OrmEmployee>() { new OrmEmployee { iEmployee = 1000, cEmployeeName = "王小明" }, new OrmEmployee { iEmployee = 2000, cEmployeeName = "李小華" }, } }, new OrmDepartment() { iDepartment = 2, cDepartmentName = "研發部", oEmployee = new System.Collections.Generic.List<OrmEmployee>() { new OrmEmployee { iEmployee = 3000, cEmployeeName = "張大頭" }, new OrmEmployee { iEmployee = 4000, cEmployeeName = "林小英" }, } }, }; //列舉出所有的員工編號與姓名 var oSelectMany_1 = oList.SelectMany(x => x.oEmployee).Select(x => $"ID={x.iEmployee};Name={x.cEmployeeName}"); foreach (var item in oSelectMany_1) { Console.WriteLine(item); } //列舉出所有的員工編號與姓名,以及所屬部門(拍扁) var oSelectMany_2 = oList.SelectMany(x => x.oEmployee, (x, y) => new { x.iDepartment, x.cDepartmentName, y.iEmployee, y.cEmployeeName }); foreach (var item in oSelectMany_2) { Console.WriteLine(item); } ReadKey(); }
輸出結果如下:
ID=1000;Name=王小明 ID=2000;Name=李小華 ID=3000;Name=張大頭 ID=4000;Name=林小英 { iDepartment = 1, cDepartmentName = 行銷部, iEmployee = 1000, cEmployeeName = 王小明 } { iDepartment = 1, cDepartmentName = 行銷部, iEmployee = 2000, cEmployeeName = 李小華 } { iDepartment = 2, cDepartmentName = 研發部, iEmployee = 3000, cEmployeeName = 張大頭 } { iDepartment = 2, cDepartmentName = 研發部, iEmployee = 4000, cEmployeeName = 林小英 }
有些情境下我們會需要進行TableA與TableB進行交叉連接(CrossJoin)進行乘積運算,例如:要列出總共的排列組合可能性,這時候我們也可以使用SelectMany來進行運算,雖然說以這個案例來進行舉例並不太恰當,但是就將就一下湊或著看看吧。
//其實這就是oSelectMany_1的另外一種寫法,透過一次性的指令直接把職員挑出來成為IEnumerable>string>列表 var oEmployeeList = oList.SelectMany(x => x.oEmployee, (x, y) => y.cEmployeeName ); //利用SelectMany進行交互聯集 var oSelectMany_3 = oList.SelectMany(x => oEmployeeList, (x, y) => new { cName = y, iDeaprtment = x.iDepartment, cDepartmentName = x.cDepartmentName }); foreach (var item in oSelectMany_3) { Console.WriteLine(item); }
輸出結果如下,可以看到透過SelectMany進行A、B兩個資料表進行交叉連接(CrossJoin)運算,把所有的排列組合都列出來了:
{ cName = 王小明, iDeaprtment = 1, cDepartmentName = 行銷部 } { cName = 李小華, iDeaprtment = 1, cDepartmentName = 行銷部 } { cName = 張大頭, iDeaprtment = 1, cDepartmentName = 行銷部 } { cName = 林小英, iDeaprtment = 1, cDepartmentName = 行銷部 } { cName = 王小明, iDeaprtment = 2, cDepartmentName = 研發部 } { cName = 李小華, iDeaprtment = 2, cDepartmentName = 研發部 } { cName = 張大頭, iDeaprtment = 2, cDepartmentName = 研發部 } { cName = 林小英, iDeaprtment = 2, cDepartmentName = 研發部 }