2009-05-11 12 views
8

LINQ /ラムダ式を使用して左結合操作を実行する方法の例を教えてもらえますか?LINQを使用した左結合

+4

すべてのLINQラムダエクスプレスに乗って – mquander

+3

母はまだではなく、これを見て!。投稿はdownvotesに打ちこみ、実際には有効なもののように見えるので、まともな英語で質問を書き直すと思った。 – Noldorin

+2

@mquander ::::オリジナルのveを読むあなたのコメントは笑いを浮かべました。 – Brian

答えて

6

MSDNのLINQ to SQL samples pageは、これを実行する方法の例を示しています。コードは、LINQ to Objectsとほぼ同じでなければなりません。

ここでのキーはDefaultIfEmptyへの呼び出しです。

Dim q = From e In db.Employees _ 
     Group Join o In db.Orders On e Equals o.Employee Into ords = Group _ 
     From o In ords.DefaultIfEmpty _ 
     Select New With {e.FirstName, e.LastName, .Order = o} 

これをC#に変換する手助けが必要な場合は、尋ねてください。

0

IQueryable<aspnet_UsersInRole> q = db.aspnet_Roles 
        .Select(p => p.aspnet_UsersInRoles 
         .SingleOrDefault(x => x.UserId == iduser)); 

はそれが指定されたユーザ(iduserキー)と一致しないヌルで、asp.netメンバーシップからあなたの役割のリストが表示されます

0

方法I私が好きなのは、OuterCollection.SelectMany()InnerCollection.DefaultIfEmpty()を組み合わせることです。 LINQPadでは、「C#ステートメント」モードを使用して次を実行できます。

var teams = new[] 
    { 
     new { Id = 1, Name = "Tigers" }, 
     new { Id = 2, Name = "Sharks" }, 
     new { Id = 3, Name = "Rangers" }, 
    }; 

var players = new[] 
    { 
     new { Name = "Abe", TeamId = 2}, 
     new { Name = "Beth", TeamId = 4}, 
     new { Name = "Chaz", TeamId = 1}, 
     new { Name = "Dee", TeamId = 2}, 
    }; 

// SelectMany generally aggregates a collection based upon a selector: from the outer item to 
// a collection of the inner item. Adding .DefaultIfEmpty ensures that every outer item 
// will map to something, even null. This circumstance makes the query a left outer join. 
// Here we use a form of SelectMany with a second selector parameter that performs an 
// an additional transformation from the (outer,inner) pair to an arbitrary value (an 
// an anonymous type in this case.) 
var teamAndPlayer = teams.SelectMany(
    team => 
     players 
     .Where(player => player.TeamId == team.Id) 
     .DefaultIfEmpty(), 
    (team, player) => new 
     { 
      Team = team.Name, 
      Player = player != null ? player.Name : null 
     }); 

teamAndPlayer.Dump(); 

// teamAndPlayer is: 
//  { 
//   {"Tigers", "Chaz"}, 
//   {"Sharks", "Abe"}, 
//   {"Sharks", "Dee"}, 
//   {"Rangers", null} 
//  } 

これで実験している間、私は時々あなたが匿名型のインスタンス化にplayerのヌルチェックを省略することができることを見出しました。私はこれが、データベース上でLINQ-to-SQLを使用していると思います。(これらの配列の代わりに、LINQ-to-objectsや何かにすると思います。)LINQでのヌルチェックの省略は、 SQLへの変換がSQL LEFT OUTER JOINに変換されるため、外部アイテムとNULLを結合することになります。 (匿名オブジェクトのプロパティの値はnull可能でなければならないので、を安全に含める場合は、new { TeamId = (int?)player.TeamId }などが必要です。

0

よくわかっています。 nullであり、私が得た結果は、この拡張メソッドです(少し想像力で、あなただけの参加、左を作ってそれを変更することができます):

public static class extends 
{ 
    public static IEnumerable<T> LefJoinBNull<T, TKey>(this IEnumerable<T> source, IEnumerable<T> Target, Func<T, TKey> key) 
    { 
     if (source == null) 
      throw new ArgumentException("source is null"); 

     return from s in source 
       join j in Target on key.Invoke(s) equals key.Invoke(j) into gg 
       from i in gg.DefaultIfEmpty() 
       where i == null 
       select s; 
    } 
} 
関連する問題