我想获取按已链接查询的 desc 订购的请求项目的所有子项。当我尝试在另一个 SelectMany 中使用带有 DefaultIfEmpty 的 SelectMany 时:
DbSet<MyRecord<long>>().FromSql(select * from unnest({0}), object[] { NpgsqlParameter<MyRecord<long>[]> })
.SelectMany(pk => dataContext.TestItems
.Where(item => pk.Item == item.ParentId)
.SelectMany(
collectionSelector: entity => dataContext.TestQueries
.Where(a => a.QueryId == entity.EntityId)
.DefaultIfEmpty(),
resultSelector: (left, right) => new JoinResult<TestItem, TestQuery>{
Left = left,
Right = right
}
)
.OrderByDescending(result => result.Right.ObjectId)
.Select(result => result.Left))
与实体
class MyRecord<T>
{
public T Item {get;set;}
}
class JoinResult<T1, T2>
{
public T1 Left { get; set; }
public T2 Right { get; set; }
}
class TestItem
{
public int EntityId {get;set;}
public string Name {get;set;}
public int ParentId {get;set;} // link to TestItem.EntityId
}
class TestQuery
{
public int QueryId {get;set;}
}
我得到sql查询:
SELECT t0.EntityId, t0.Name, t0.ParentId
FROM (
select * from unnest(ARRAY[101,102])
) AS e
LEFT JOIN LATERAL (
SELECT c.EntityId, c.Name, c.ParentId
FROM items AS c
JOIN LATERAL (
SELECT s.QueryId
FROM queries AS q
WHERE q.QueryId = c.EntityId
) AS t ON TRUE
WHERE e.unnest = c.ParentId
ORDER BY t.QueryId DESC
) AS t0 ON TRUE
但我希望在 CROSS JOIN 中使用 LEFT JOIN。如何停止第一个 SelectMany 上的转换查询并获取 smh:
SELECT t0.EntityId, t0.Name, t0.ParentId
FROM (
select * from unnest(ARRAY[101,102])
) AS e
JOIN LATERAL (
SELECT c.EntityId, c.Name, c.ParentId
FROM items AS c
LEFT JOIN LATERAL (
SELECT s.QueryId
FROM queries AS q
WHERE q.QueryId = c.EntityId
) AS t ON TRUE
WHERE e.unnest = c.ParentId
ORDER BY t.QueryId DESC
) AS t0 ON TRUE
我认为 DefaultIfEmpty 将 SelectMany 设置为 LEFT JOIN 但翻译必须在内部扩展上。如何更改查询以获得此签名上的预期 sql?
我尝试使用 GroupJoin,但此功能破坏了许多现有逻辑,因此我认为无法访问。 我们所有的构建都在 .net 6 和 8 中重复了这种行为
您的代码在语法上不太正确,我不得不假设您的意图。
您的主要问题是,当您只想订购内部子查询时,您正在订购外部查询。
还有:
.Include
context.Database.SqlQuery
来代替。dataContext.Database.SqlQuery<long>($"select * from unnest({ new NpgsqlParameter("@items", listHere) })")
.SelectMany(pk => dataContext.TestItems
.Where(item => pk.Item == item.ParentId)
.Include(entity => dataContext.TestQueries
.OrderByDescending(result => result.Right.ObjectId)
)
.DefaultIfEmpty()
)