4

我想创建一个相当于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.aspxJoinMSDN http://msdn.microsoft.com/fr-fr/library/bb534675的帮助) .aspx )

GroupJoinand的最后一个参数Join是可选的(通过重载)并且通常不使用。它是一个允许您指定如何与 比较r.RecipeID的功能i.RecipeID。由于RecipeID必须是整数,所以使用默认比较器是一个不错的选择。所以让它:

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});

更新

@usr 完美地评论说Join执行 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.xml 中获得的结果相同。

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 回答
0

试试这个

var model = db.Recipe
            .GroupJoin(db.Instructions.Where(instruction => instruction.SomeFlag > 0),r => r.RecipeID,i => i.RecipeID, (r, i) => new { Recipe = r, Instructions = i })
            .SelectMany(t => t.Instructions.DefaultIfEmpty(),(t, Instructions) => new
            {
                 Recipe = t.Recipe,
                 Instructions = Instructions
            });
于 2019-10-07T13:17:55.280 回答