EF仅在所有孩子都具有特定身份时才选择父母

时间:2017-07-12 19:14:15

标签: entity-framework

我想只选择那些all名儿童身份= success的父母 我还希望将这些孩子包括在过滤父母中

因此返回预期结果的相应SQL语句是

select * from Parent p 
join Child c on c.ParentId = p.ParentId
where c.Status = 'success'

我想用EF

写相同的内容
  var result = await _dbcontext.Parents
            .Where(x => x.Children.All(y => y.Status == "success"))
            .ToListAsync();

这不起作用

更新1
抱歉,上面的SQL语句也没有按预期工作。

它应该只返回所有孩子都具有身份success的父母。因此,如果父母有5个孩子,4个孩子有success而1个没有success那么它不应该返回那个父母

更新2
我已经禁用了延迟加载

        dbContext.Configuration.LazyLoadingEnabled = false;// turn-off loading on-demand
        dbContext.Configuration.ProxyCreationEnabled = false;// turn-off dynamic proxy class generation

暂时不允许在select中包含子项,只过滤父项。所以下面的EF查询

 var result = await _dbcontext.Parents                
        .Where(x => x.Children.All(y => y.Status == "success"))
        .ToListAsync();

生成以下SQL

SELECT 
    [Extent1].[ParentId] AS [ParentId],         
    [Extent1].[DocumentName] AS [DocumentName],     
    [Extent1].[CreatedDateTime] AS [CreatedDateTime], 
    [Extent1].[ModifiedDateTime] AS [ModifiedDateTime],     
    FROM [dbo].[Parent] AS [Extent1]
    WHERE  NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[Child] AS [Extent2]
        WHERE ([Extent1].[ParentId] = [Extent2].[ParentId]) AND (('success' <> [Extent2].[Status]) OR (CASE WHEN ('success' = [Extent2].[Status]) THEN cast(1 as bit) WHEN ('success' <> [Extent2].[Status]) THEN cast(0 as bit) END IS NULL))
    )

3 个答案:

答案 0 :(得分:1)

您的SQL语句不正确,您将获得所有父母至少有一个孩子的成功&#34;状态。但这不是重点。

由于你不共享你的模型,这可能是一个急切的\懒惰负载问题。看起来你的EF表达在逻辑上是正常的。所以你可以这样试试:

var result = await _dbcontext.Parents.Include(x => x.Children).
        .Where(x => x.Children.All(y => y.Status == "success"))
        .ToListAsync();

答案 1 :(得分:0)

我想我找到了它。我还必须检查父母是否有孩子。我的代码是回来没有孩子的父母

var result = await _dbcontext.Parents
                .Include(x=>x.Children)                
                .Where(x => x.Children.Any() && x.Children.All(y => y.Status == "success"))
                .ToListAsync();

答案 2 :(得分:0)

为什么不选择所有成功的孩子,并获得他们的独特父母:

var result = dbContext.Children                  // get all children
   .Where(child => child.Status == "success")    // keep only the successful ones
   .Select(child => child.Parent);               // select their parents
   .Distinct();                                  // remove duplicate parents

为此,您需要在实体框架中设置proper one-to-many relationship

class Parent
{
    ...
    // a parent has many children:
    public virtual ICollection<Child> Children {get; set;}
}

class Child
{
    ...
    // A Child belongs to one parent via foreign key
    public int ParentId {get; set;}
    public virtual Parent Parent {get; set;}
}