SQL で外部結合をする場合は、さくっと left join や *= などを使えば良いのですが、LINQ だといまいち不明。
だったので、探してみました。
Visual Studio 2010 – Visual C#
方法 : 左外部結合を実行する (C# プログラミング ガイド)
http://msdn.microsoft.com/ja-jp/library/bb397895.aspx
という感じで、モロ、そのままの記事がありました。以前は、LINQ関係は調べるのが大変だったのですが、これは良さそうですね。
備忘録も込みで、解説を加えておくと、
- Person、Pet というテーブルがあります。
- Person(人)は、Pet(ペット)を飼っている、というイメージですね。
- Personには、ペットを飼っていない人もいます。
public class Person
{
public string FirstName { get; set; }
public int? PetID { get; set; }
}
public class Pet
{
public int ID { get; set; }
public string PetName { get; set; }
}
List<Person> persons;
List<Pet> pets;
こんな風にデータを初期化しておきます。
// 初期化
private void button1_Click(object sender, EventArgs e)
{
persons = new List<Person>();
persons.Add(new Person() { FirstName = “masuda”, PetID = 1 });
persons.Add(new Person() { FirstName = “tomoaki”, PetID = null });
persons.Add(new Person() { FirstName = “kyonpu”, PetID = 2 });pets = new List<Pet>();
pets.Add( new Pet() { ID=1, PetName=”taro” });
pets.Add( new Pet() { ID=2, PetName=”risumo” });
}
■ペットを飼っている人(内部結合)
// 内部結合
private void button2_Click(object sender, EventArgs e)
{
// ペットがいる人を表示
var ret = from pe in persons
join pet in pets on pe.PetID equals pet.ID
select new { pe.FirstName, pet.PetName };foreach (var it in ret)
{
Debug.Print(it.ToString());
}
}
■ペットを飼っている人もそうでない人も表示(外部結合)
// 外部結合
private void button3_Click(object sender, EventArgs e)
{
// ペットがいる/いないに関わらず表示
var ret = from pe in persons
join pet in pets on pe.PetID equals pet.ID into sub
from t in sub.DefaultIfEmpty()
select new { pe.FirstName, PetName = ( t == null ? “”: t.PetName )};foreach (var it in ret)
{
Debug.Print(it.ToString());
}
}
■ペットを飼っていない人だけを表示(null比較)
// 外部結合(nullのみ抽出)
private void button4_Click(object sender, EventArgs e)
{
// ペットがいない人を表示
var ret = from pe in persons
join pet in pets on pe.PetID equals pet.ID into sub
from t in sub.DefaultIfEmpty()
where t == null
select new { pe.FirstName };foreach (var it in ret)
{
Debug.Print(it.ToString());
}
}
こんな風に、一度 into を使ってサブテーブル(sub)を用意してから、DefaultIfEmpty メソッドで外部結合を実現する、という方法になります。