LINQでクロス結合
クロス結合(CROSS JOIN)はLINQを使ってどうやって書くんだろうと気になったので調べてみました。
SQLでもほとんど使わないのでC#でもほとんど使わないとは思いますが・・・。重複ありのすべての組合わせを出したいときに使えるかなーと思います。まぁほとんど使わないんですが。
T-SQLでクロス結合
まずはSQLでサンプルを書いてみます。
-- 性別テーブル if object_id('tempdb..#Gender') is not null drop table #Gender; select * into #Gender from (values(N'男性'), (N'女性')) as Temp(Gender); select * from #Gender; /* Gender ------ 男性 女性 */ -- 年代テーブル if object_id('tempdb..#Year') is not null drop table #Year; select * into #Year from (values(N'10代'), (N'20代'), (N'30代')) as Temp(Year); select * from #Year; /* Year ---- 10代 20代 30代 */ -- クロス結合 select * from #Gender cross join #Year; /* Gender Year ------ ---- 男性 10代 男性 20代 男性 30代 女性 10代 女性 20代 女性 30代 */
クロス結合を使うと、性別と年代の重複ありの組合わせを作ることができます。
LINQでクロス結合
LINQで同じことをするにはSelectManyを使うといいみたいです。
Enumerable.SelectMany メソッド (System.Linq)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp { class Program { static void Main(string[] args) { var genders = new [] { "男性", "女性" }; var years = new [] { "10代", "20代", "30代" }; // クロス結合 var entries = genders.SelectMany( gender => years, // gendersの各要素に対して常にyearsを返す (gender, year) => new { Gender = gender, Year = year } ); foreach (var entry in entries) { Console.WriteLine("{0} {1}", entry.Gender, entry.Year); } /* 男性 10代 男性 20代 男性 30代 女性 10代 女性 20代 女性 30代 */ } } }
gendersの各要素ごとに呼び出されるcollectionSelector関数で常にyearsを返すという感じです。
他に良い方法があるのかしら。