提问者:小点点

在以实体框架为核心的联接表上使用多个OR和filter表示查询


这是我的模型

class Parent { int Id; string Name; List<Child> Childs; } // name is unique
class Child { int Id; int ParentId; string Name; Parent Parent; } // couple (id, name) is unique

对于给定的夫妇列表(父名,子名),我想获得夫妇(父名,子名),其中如果具有给定名称的父名存在,但子名不存在,子名可以为空。 SQL查询如下所示:

SELECT * FROM parents p
LEFT JOIN childs c ON c.parent_id = p.id
WHERE p.name = 'parent1' AND (c.name IS NULL OR c.name = 'child1')
OR p.name = 'parent2' AND (c.name IS NULL OR c.name = 'child2')
OR p.name = 'parent3' AND (c.name IS NULL OR c.name = 'child3')
or p.name = 'parent4' AND (c.name IS NULL OR c.name = 'child4');

我尝试用EntityFramework核心对Or和False方法使用PredicateBuilder来表达这个查询

var predicate = PredicateBuilder.False<Parent>()
    .Or(p => p.Name == "parent1" && p.Childs.Any(c => c.Name == "child1"))
    .Or(p => p.Name == "parent2" && p.Childs.Any(c => c.Name == "child2"))
    .Or(p => p.Name == "parent3" && p.Childs.Any(c => c.Name == "child3"))
    .Or(p => p.Name == "parent4" && p.Childs.Any(c => c.Name == "child4"));
var p = await _db.Parents
    .Include(p => p.Childs)
    .Where(predicate)
    .ToArrayAsync();

这是我能得到的最接近的结果,但这没有得到预期的结果:

  • 如果子级不存在,则父级在结果集中不存在
  • parent.childs包含父级的所有子级,而不是只包含所需的子级

我的quey可以用实体框架表达吗?


共1个答案

匿名用户

parent.childs包含父级的所有子级,而不是只包含所需的子级

筛选的include即将到来,但尚未实现。 我有点不明白为什么你认为它实际上会过滤,因为你的代码清楚地说明要包括所有的孩子。。。

。包括(p=>p.Childs)

意思包括孩子们(顺便说一句,childs是糟糕的英语--复数是children)。 那里没有过滤器。

关于过滤的包括:

在EF内核中包含滤波

此处引用相关部件:

“最后,此功能已从EF Core preview version 5.0.0-preview.3.20181.2开始实现,并将在EF Core version 5.0.0中得到GA”

但即使这样,您也必须进行筛选(例如,将一个where放到include中,而不仅仅是告诉它获取所有它们)。