Я использую EntityFramework Core со схемой базы данных, которая упрощается до этого:
public class Parent
{
public int ID { get; set; }
}
public class Child
{
public int ID { get; set; }
public bool Include { get; set; }
}
public class Link
{
public int FromID { get; set; }
public int ToID { get; set; }
}
Где родитель связан с ребенком записью в третьей таблице.
Родитель к ссылке один-ко-многим
Ссылка на ребенка - один к одному
Я не могу изменить схему базы данных в рамках этой работы.
Я пытаюсь вернуть экземпляры Parent, которые связаны хотя бы с одним ребенком, и где ВСЕ дети соответствуют определенным критериям (в этом примере include == true
)
Я пробовал много разных запросов, включая приведенный ниже, который работает в этом тестовом сценарии, но, похоже, не очень хорошо масштабируется.
var ParentList = new[]
{
new Parent {ID = 1}, //3 children, 1 fails criteria
new Parent {ID = 2}, //2 children, all pass criteria
new Parent {ID = 3} //no children
};
var ChildList = new[]
{
new Child {ID = 11, Include = true},
new Child {ID = 12, Include = true},
new Child {ID = 13, Include = false},
new Child {ID = 21, Include = true},
new Child {ID = 22, Include = true},
};
var LinkList = new[]
{
new Link {FromID = 1, ToID = 11},
new Link {FromID = 1, ToID = 12},
new Link {FromID = 1, ToID = 13},
new Link {FromID = 2, ToID = 21},
new Link {FromID = 2, ToID = 22},
};
var relevant = (from parent in ParentList
join l in LinkList on parent.ID equals l.FromID into links
from linkedChildren in (
from link in links
join child in ChildList on link.ToID equals child.ID into children
from child in children
group child by link.FromID into kids
select kids.AsEnumerable())
where linkedChildren.All(x => x.Include)
select new { parent, linkedChildren }).ToList();
Assert.Single(relevant);
Assert.Equal(2, relevant.First().parent.ID);