c#のLinqを使ってみる(2)

こんにちは。きわさです。

前回に引き続き、C#のLinqについてです。
今回はJoinです。
二つのリストから新しいリストを生成します。

例えば以下のようなユーザークラスと会社クラスがあり、
ユーザークラスのCompanyIdには、所属する会社(Company)のId入ります。

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CompanyId { get; set; }
}

public class  Company
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Date { get; set; }
    public string Address { get; set; }
}

そして、以下のように全ユーザー、全会社のリストがそれぞれあるとします。

List<User> userList = new List<User>() 
{
    // 全ユーザーの情報   
}

List<Company> companyList = new List<Company>() 
{
    // 全会社の情報
}

そこで、あるユーザーの所属する会社名と住所を知りたくなりました。
Linqを使わずに書くと以下のようなループループな感じになりかねません。

var userId = 3; // 対象ユーザー

Company userCompany = null; 
foreach (var user in userList) 
{
    if (user.Id == userId)
    {
        foreach (var company in companyList)
        {
            if (user.CompanyId == company.Id)
            {
                userCompany = company;
                break;
            }
        }
        break;
    }    
}

前回のWhereを使ってみると次のように書くことができます。

var user = userList.Where(u => u.Id == userId).First();
var company = companyList.Where(c => c.Id == user.CompanyId).First();

.First()は1件目の要素を取得できます。
.Where(u => u.Id == userId).First()は直接
.First(u => u.Id == userId) と書くこともできます。

上記の場合のように、対象ユーザー一人分等であれば、よいかもしれませんが、
複数のユーザーの会社情報を一覧にしたい場合などではJoinが使えます。

var list = userList.Join(companyList,
                         u => u.CompanyId,
                         c => c.Id,
                         (u, c) => new 
                         { 
                             UserId = u.Id,
                             UserName = u.Name, 
                             CompanyName = c.Name,
                             CompanyAddress = c.Address, 
                         })
                   .ToList();

このようにすると、listは ユーザーID、氏名、会社名、会社住所をメンバにもつオブジェクトのリストとなります。
new { } の部分は 定義済みクラスで new XXX() { } のようにもできます。

あとは該当のユーザーの情報をとるなり、全ユーザーを一覧表示するなり、できます。

ループループしてなくてよいですね。

スポンサーリンク