4

に相当する LINQ 結合ステートメントを作成したいLeft Join

私のテーブルは次のように設定されています:

Recipe
    RecipeID
    ...

Instruction
    RecipeID
    StepID
    SomeFlag
    ...

同等の SQL:

SELECT *
FROM Recipe r
LEFT JOIN Instruction i
    ON r.RecipeID = i.RecipeID
    AND SomeFlag > 0

これは私がこれまでに持っているものです:

var tmp = db.Recipe
    .GroupJoin(
        db.Instruction,
        r => r.RecipeID,
        i => i.RecipeID,
        (r, i) => new {r, i},
        ???);

まず、GroupJoinこのタイプの操作の正しい選択はありますか? 私の理解では、Join は SQL の「Inner Join」に相当し、GroupJoin は「Left Join」に相当します。次に、目的の結果を得るための正しい構文は何ですか? 私はしばらく探していましたが、拡張メソッドを使用して適切な答えを見つけることができないようです。

4

3 に答える 3

6

GroupJoin( : MSDN http://msdn.microsoft.com/en-us/library/bb535047.aspxおよびJoinMSDN http://msdn.microsoft.com/fr-fr/library/bb534675のヘルプを読むことを忘れないでください。 .aspx )

GroupJoinandの最後の引数はJoin(オーバーロードによる) オプションであり、通常は使用されません。r.RecipeIDとの比較方法を指定できる機能ですi.RecipeIDRecipeID整数でなければならないため、デフォルトの比較子を使用することをお勧めします。だからそれをしましょう:

var tmp = db.Recipe
    .Join(db.Instruction,
          r => r.RecipeID,
          i => i.RecipeID,
          (r, i) => new {r, i});

ここで必要なのは、SomeFlag > 0. 入社前にやってみませんか?このような:

var tmp = db.Recipe
    .Join(db.Instruction.Where(instruction => instruction.SomeFlag > 0),
          r => r.RecipeID,
          i => i.RecipeID,
          (r, i) => new {r, i});

アップデート

Join@usr は、INNER JOIN を実行すると完全にコメントしています。

お気づきかもしれませんが、LINQ には、INNER、OUTER、LEFT、RIGHT 結合の異なるメソッドはありません。特定の SQL 結合に相当する LINQ を知るには、MSDN ( http://msdn.microsoft.com/en-us/library/vstudio/bb397676.aspx )でヘルプを見つけることができます。

var tmp = from recipe in Recipes
          join instruction in
              from instruction in Instructions
              where instruction.SomeFlag > 0
              select instruction
          on recipe.RecipeID equals instruction.RecipeID into gj
          from instruction in gj.DefaultIfEmpty()
          select new
          {
              recipe,
              instruction
          };

拡張メソッドを使用すると、少し醜い解決策になります:

var tmp = Recipes.GroupJoin(Instructions.Where(instruction => instruction.SomeFlag > 0),
                            recipe => recipe.RecipeID,
                            instruction => instruction.RecipeID,
                            (recipe, gj) => new { recipe, gj })
                 .SelectMany(@t => @t.gj.DefaultIfEmpty(), 
                             (@t, instruction) => new
                             {
                                 @t.recipe,
                                 instruction
                             });
于 2013-01-21T17:41:14.243 に答える
1

理解できなかった場合は教えてください。ただし、この拡張メソッドは、SQLで取得したのと同じ結果を返します。

public static IEnumerable<ResultType> GetLeftJoinWith(this IEnumerable<Recipe>, IEnumerable<Instructions> ins)
{
    var filteredInstructions = ins.Where(x => x.SomeFlag > 0);

    var res = from r in rec
              join tmpIns in filteredInstructions on r.RecipeID equals t.RecipeID into instructions
              from instruction in instructions.DefaultIfEmpty()
              select new { r, instruction };

   return res;
}
于 2013-01-21T18:01:25.070 に答える