如何写这个查询在LINQ到实体:LEFT JOIN查询工作不正常
SELECT * FROM TableA a LEFT JOIN TableB b ON a.Id = b.TableAId WHERE ISNULL(b.Id) OR b.FieldA = 1
关系是1对多,但限制b.FIeldA = 1是确保实际数据返回的结果为1-0 ... 1,这意味着返回记录的数量应该等于TableA中的记录。我需要从TableA获取所有数据,并从TableB中加入数据。我试图用这个查询,其实际上像INNER JOIN一样预先形成(来自TableA的记录没有在TableB中的相关记录未被检索到)
Vladislav建议查询下面,我已经在第一个查询中添加了额外的过滤:
var query = (from x in myParentClasses.Include(x => x.TableBChildren)
where !x.TableBChildren.Any(y => y.FieldA == 1)
select x)
.Concat(
from x in myParentClasses.Include(x => x.TableBChildren)
where x.TableBChildren.Any(y => y.FieldA == 1 || y.Id == null)
select x)
.ToList();
生成的SQL是这样的:
SELECT [Project1][...]
FROM (SELECT [Extent1].[...],
[Extent2].[...],
[Extent3].[...],
CASE
WHEN ([Extent3].[Id] IS NULL) THEN CAST(NULL AS int)
ELSE 1
END AS [C1]
FROM [dbo].[ParentTable] AS [Extent1]
LEFT OUTER JOIN [dbo].[ReferenceTable] AS [Extent2]
ON [Extent1].[ReferenceId] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[ChildrenTable] AS [Extent3]
ON [Extent1].[Id] = [Extent3].[ParentId]
WHERE [Extent1].[FieldA] = 1 /* @p__linq__0 */) AS [Project1]
ORDER BY [Project1].[Id] ASC,
[Project1].[Id1] ASC,
[Project1].[C1] ASC
谢谢, 戈兰
Hi Ladislav, 正如你可以在我的第一篇文章中看到的,我在TableB中过滤数据,y => y.FieldA == 1.在过滤TableB数据之后,我需要用TableA加入它,包含tableA的所有记录和来自TableB的相关数据,但只适用滤波器(y => y.FieldA == 1)。 – Goran
但\我需要它作为可编辑的,而不是只读的。我不知道我明白你为什么说过滤不可能过滤关系,如果在第一个查询而不是.Any()我把我放.Any(y => y.FieldA == 1)然后我过滤通过关系记录。 我在这里错过了什么,或者我不太明白你在说什么? – Goran
您只能过滤顶级实体 - 这是第一个查询中的任何操作,但不能过滤内部关系。不允许。如果你需要实体可编辑,你必须加载所有'TableBChildren',而不是它们或使用单独的查询来加载它们过滤。您还可以在应用程序端使用已过滤的集合加载投影和重建/重新绑定实体。 –