【问题标题】:Fluent LINQ - Select a list of parents that contains a list of children where a subset of children are presentFluent LINQ - 选择一个父列表,其中包含一个子集的子列表
【发布时间】:2014-09-15 21:37:47
【问题描述】:

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

无论如何,我要做的是选择一个父对象,它包含 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)));

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

【问题讨论】:

  • +1 表示您对标题的评论(所以不会让我引用它,因为它检测到我的评论是负面或贬义的)

标签: c# sql linq fluent


【解决方案1】:

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

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

【讨论】:

  • 使用Any 子句代替.Select().Contains 会更简洁:p.Children.Any(c =&gt; c.SomeValue == v)
  • 啊!我不敢相信我没有考虑到这一点。感谢您的帮助。
【解决方案2】:

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

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);

【讨论】:

  • 这有几个问题,主要是这将不允许搜索条件的动态列表而不添加额外的查询,这会很快破坏性能,并且 OP 专门要求 Fluent Linq
猜你喜欢
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-06
  • 2015-12-17
相关资源
最近更新 更多