Sql 子条件不匹配时不包括父实体

Sql 子条件不匹配时不包括父实体,sql,linq,entity-framework-6,Sql,Linq,Entity Framework 6,我有一个查询,其中我必须返回一些实体及其子实体 目前,如果没有子级,则也不会返回父级。我想要的是所有父母的列表,如果有孩子,就把它包括在内 我的Linq查询当前如下所示: var query = (from parent in Context.Parents join child in Context.Children on child.ParentId.DefaultIfEmpty() equals parent.Id where child.S

我有一个查询,其中我必须返回一些实体及其子实体

目前,如果没有子级,则也不会返回父级。我想要的是所有父母的列表,如果有孩子,就把它包括在内

我的Linq查询当前如下所示:

var query = (from parent in Context.Parents
            join child in Context.Children on child.ParentId.DefaultIfEmpty() equals parent.Id
            where child.SomeProperty == SomeValue
            select new {parent, child});

var result = query.ToList().Select(e => e.parent).Distinct().ToList();
这将生成以下SQL查询

SELECT 
    [Extent1].[ParentId] AS [ParentId], 
    [Join1].[ChildId] AS [ChildId], 
    [Join1].[SomeProperty] AS [SomeProperty], 
    FROM  [dbo].[Parent] AS [Extent1]
    INNER JOIN  (SELECT [Extent2].[ChildId] AS [ChildId], 
                        [Extent2].[SomeProperty] AS [SomeProperty]
        FROM   ( SELECT 1 AS X ) AS [SingleRowTable1]
        LEFT OUTER JOIN [dbo].[Child] AS [Extent2] ON 1 = 1 ) AS [Join1] ON [Extent1].[ParentId] = [Join1].[ParentId]
    WHERE [Join1].[SomeProperty] = @p__linq__0
我已经成功地创建了返回我想要的结果的SQL查询,但是我仍然无法在Linq中转换它

SELECT Distinct Parent.ParentID, fullData.ChildID 
    FROM Parent left outer join 
    (select Child.ParentId, Child.SomeProperty, Child.EmployeurSubsideID 
        from Child 
        Where Child.SomeProperty = 'SomeValue'  ) as fullData on Parent.ParentID = fullData.ParentID
诸如此类

var query = (from parent in Context.Parents
            join child in Context.Children on child.ParentId equals parent.Id
            into ch from c in ch.DefaultIfEmpty()
            where c == null || c.SomeProperty == SomeValue
            select new {parent, c});


假设外键设置正确,请注意子项的属性名称可能不同

这是一个经典的
左外连接
,带有附加的右侧过滤器

您有两个选项(均有效):

(A) 在连接之前应用右侧过滤器

var query = 
    from parent in Context.Parents
    join child in Context.Children
        .Where(child => child.SomeProperty == SomeValue)
    on parent.Id equals child.ParentId into children
    from child in children.DefaultIfEmpty()
    select new { parent, child };
(B) 对联接使用组合键

var query = 
    from parent in Context.Parents
    join child in Context.Children on new { K1 = parent.Id, K2 = SomeValue }
    equals new { K1 = child.ParentId, K2 = child.SomeProperty } into children
    from child in children.DefaultIfEmpty()
    select new { parent, child };
实际上,在LINQ to Entities中,您有第三个选项:

(C) 使用
where
而不是
join
(模式由查询转换器识别,生成的SQL查询仍将使用
左外部联接
):


对于你的第二个问题:我觉得它根本不会过滤孩子们。它将接受所有子项,但不会接受所有子项与第一次查询的条件不匹配的父项,如果,我有以下错误:“无法解析符号'DefaultIfEmpty'修复了第一个查询中的语法,在第二个查询中,如果父项没有子项,则将选择它,或者如果任何子项与条件匹配,则将选择父项。”。那似乎是你想要的条件。
var query = 
    from parent in Context.Parents
    join child in Context.Children on new { K1 = parent.Id, K2 = SomeValue }
    equals new { K1 = child.ParentId, K2 = child.SomeProperty } into children
    from child in children.DefaultIfEmpty()
    select new { parent, child };
var query = 
    from parent in Context.Parents
    from child in Context.Children
        .Where(child => parent.Id == child.ParentId && child.SomeProperty == SomeValue)
        .DefaultIfEmpty()
    select new { parent, child };