SQL 到 Linq Lambda

SQL to Linq Lambda

有人知道如何在 LINQ Lambda 的外部连接上转换它吗?

我想使用 lambda linq 来实现这个

SELECT * FROM Posts as A LEFT JOIN Reactions as B on A.Id = B.PostId AND @userId = b.userid

这是我当前的 linq 代码

 return await _dbContext.Posts
           .GroupJoin(_dbContext.Reactions,
           post => post.Id, reaction => reaction.PostId,
           (post, reactions) => new { post, reactions })
           .SelectMany(x => x.reactions.DefaultIfEmpty(),
           (post, reaction) => new { post.post, reaction })

left outer join 是一个连接,其中返回第一个集合的每个元素,无论它是否在第二个集合中有任何相关元素。您可以使用 LINQ 通过对组联接的结果调用 DefaultIfEmpty 方法来执行左外部联接。

您可以使用这种方法

查询语法:

var query = (from post in Posts
            join reaction in Reactions
            on post.Id equals reaction.PostId
            into reaction
            from reaction in reaction.DefaultIfEmpty()
            select new
            {
                post.Id,
                //prod.Foo1,
                //post.Foo2,
                //reaction.Foo3,
                //reaction.Foo4,
                //you can select other fields too
            }).OrderBy(ps => ps.Id);

有关详细信息,请访问 Perform left outer joins

您可以在 SQL 中以两种不同的方式完成您想要完成的任务,并且这些方式可以转换为 Linq。

根据您的情况(数据量、索引等),您可能需要一个或另一个

选项 A:合并过滤后的数据

SELECT a.Name, b.* 
FROM 
    tableA 
    LEFT JOIN tableB on 
        b.Action='delete' AND a.Id = b.Id

在 LINQ 中将被翻译成类似于:

var query =
    from a in db.TableA
    join pet in db.TableB.Where(x => x.Action=="delete") on a equals b.TableA into gj
    from leftJoined in gj.DefaultIfEmpty()

并使用方法语法:

var query = tableA
    .GroupJoin(
        tableB.Where(x => x.Action == "delete"),
        tableA => tableA, 
        tableB => tableB.tableA,
        (tableA, tableBs) => new {tableA, tableBs}
    ).SelectMany(x => x.tableBs.DefaultIfEmpty())

选项 B:进行连接然后过滤数据

SELECT a.Name, b.* 
FROM 
    tableA 
    LEFT JOIN tableB on a.Id = b.Id 
WHERE 
    b.Id = NULL OR b.Action='delete'

将被翻译成:

var query =
    from a in db.TableA
    join pet in db.TableB on a equals b.TableA into gj
    from leftJoined in gj.DefaultIfEmpty()
    where lefjoined == null || leftjoined.Action == "delete"

通常你不会。在 LINQ 中根本没有必要像那样展平相关数据。只需以其自然形状获取数据:

_dbContext.Posts.Include(p => p.Reactions)

这 returns Post 和任何反应,而不必为每个反应重复 Post 数据,或者 Post 没有反应的空值。