Fluent LINQ-选择一个包含子项列表的父项列表,其中存在子项子集

本文关键字:列表 子集 存在 LINQ- 选择 一个 Fluent 包含 | 更新日期: 2023-09-27 18:22:02

这个标题是最糟糕的。。。

无论如何,我要做的是选择一个父对象,它包含n个子对象。我将传入子对象必须匹配的条件列表(1..n)。为了简洁起见,下面是我正在使用的类:

public class Parent {
     public int Id { get; set; }
     public List<Child> Children { get; set; }
}
public class Child { 
    public int Id { get; set; }
    public int ParentId { get; set; }
    public int SomeValue { get; set; }
}

我要找的是一个包含与我在中传递的所有SomeValues相匹配的孩子的家长列表

所以如果我有:

Parent 1
    Child 1, SomeValue 10
    Child 2, SomeValue 20
    Child 3, SomeValue 40
Parent 2
    Child 4, SomeValue 10
    Child 5, SomeValue 20
    Child 5, SomeValue 50

并且myList是[10,50],它只需要返回Parent 2。如果myList是[10,20],则应该返回双亲。最后,如果myList是[10,20,60],则不应返回任何内容。

我认为以下内容不起作用,因为孩子们拥有的不在列表中的值会将其从结果中删除(对吧?)

parents.where(p => p.children.all(c => myList.contains(c.SomeValue)));

任何一个都不起作用,因为只要它的一个孩子匹配,它就会返回任何东西。我需要确保父项有一个与myList中的每个项匹配的子项。我还想过添加一个计数,以确保匹配的项目至少与myList.length一样大,但这可能不起作用,因为SomeValue在子集合中不必是不同的(我想我可以在子集合的SomeValues上运行不同的子选择?)

Fluent LINQ-选择一个包含子项列表的父项列表,其中存在子项子集

您可以翻转您的条件,并检查以确保所有列表值都包含在Children集合中:

var matches = parents.Where(p => myList.All(v => p.Children.Select(c => c.SomeValue).Contains(v)));

下面是一些输出的粗略代码:

10,20
1
2
10,50
2
var parents = new List<Parent>
            {
                new Parent
                {
                    Id = 1,
                    Children =
                        new List<Child>
                        {
                            new Child {SomeValue = 10},
                            new Child {SomeValue = 20},
                            new Child {SomeValue = 40}
                        }
                },
                new Parent
                {
                    Id = 2,
                    Children =
                        new List<Child>
                        {
                            new Child {SomeValue = 10},
                            new Child {SomeValue = 20},
                            new Child {SomeValue = 50}
                        }
                }
            };
            var val1 = 10;
            var val2 = 20;
            var query = from a in parents
                from b in a.Children
                where b.SomeValue == val1
                select a;
            var query2 = from a in parents
                        from b in a.Children
                        where b.SomeValue == val2
                        select a;
            Console.WriteLine("10,20");
            foreach(var parent in query.ToList().Intersect(query2.ToList()))
                Console.WriteLine(parent.Id);
            val1 = 10;
            val2 = 50;
            Console.WriteLine("10,50");
            foreach (var parent in query.ToList().Intersect(query2.ToList()))
                Console.WriteLine(parent.Id);