简体   繁体   English

C#LINQ-根据另一个列表内的子属性返回类型化的过滤列表

[英]C# LINQ - Return a typed filtered list based on a child property that is inside another list

Given the Objects : 给定对象:

class Parent
{
    private int id;

    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    private List<Child> childrenList;

    public List<Child> ChildrenList
    {
        get { return childrenList; }
        set { childrenList = value; }
    }
}

class Child
{
    private int idSub;

    public int IdSub
    {
        get { return idSub; }
        set { idSub = value; }
    }

    private bool isST;

    public bool IsST
    {
        get { return isST; }
        set { isST = value; }
    }
}

I have a List<Parent> parentList = new List<Parent>() and inside Parent object there is a list of Child which is called ChildrenList. 我有一个List<Parent> parentList = new List<Parent>()并且在Parent对象内有一个称为List<Parent> parentList = new List<Parent>()Child列表。

Child has a property IsST . Child拥有财产IsST

I want to return only the Child which has the property IsST equals true and if the Parent doesn't satisfy the condition, doesn't need to be returned. 我只想返回具有IsST属性等于true的Child ,并且如果Parent不满足该条件,则不需要返回。

And both lists returned, need to be typed with its respectively types. 并且返回的两个列表都需要分别输入其类型。

What I have so far: 到目前为止,我有:

List<Parent> parentList = new List<Parent>()
{
    new Parent()
    {
        Id = 1,
        ChildrenList = new List<Child>()
        {
           new Child()
           {
               IdSub = 1,
               IsST = true
           },
           new Child()
           {
               IdSub = 2,
               IsST = true
           }
        }
    },
     new Parent()
    {
        Id = 2,
        ChildrenList = new List<Child>()
        {
           new Child()
           {
               IdSub = 3,
               IsST = false
           },
           new Child()
           {
               IdSub = 4,
               IsST = true
           }
        }
    },
     new Parent()
    {
        Id = 3,
        ChildrenList = new List<Child>()
        {
           new Child()
           {
               IdSub = 5,
               IsST = false
           },
           new Child()
           {
               IdSub = 6,
               IsST = false
           }
        }
    }
};


var parentFilteredList = parentList
            .Select(c => c.ChildrenList
                            .Where(d => d.IsST)
                            .ToList())
            .ToList();

But the list of parents in the parentFilteredList it's not of type List<Parent> . 但是parentFilteredList中的父母列表不是List<Parent>类型。

Result_so_far

I need it to be List<Parent> because the Parent object in the real case there are a lot of properties, as well as the Child . 我需要它是List<Parent>因为在实际情况下, Parent对象以及Child都有很多属性。 Select new it's not an option. Select new选项是不可行的。

Any help? 有什么帮助吗?

var parentFilteredList = parentList
            .Select(c => c.ChildrenList
                            .Where(d => d.IsST)
                            .ToList())
            .ToList();

In the following statement you are selecting the childrenList. 在下面的语句中,您正在选择childrenList。

var parentFilteredList = parentList
        .Where(c => c.ChildrenList.Any(d => d.IsST)).ToList();

If you are looking to return all the parents where at least one child's ST is true - 如果您希望返回所有至少有一个孩子的ST的父母,则-

var parentFilteredList = parentList
     .Where(c => c.ChildrenList.Any(d => d.IsST))
     .ToList();

Or if you want to also filter the children's list inside these parents - 或者,如果您也要过滤这些父母中的孩子名单,

var parentFilteredList = parentList
     .Where(c => c.ChildrenList.Any(d => d.IsST))
     .Select(c => 
         {
             c.ChildrenList = c.ChildrenList.Where(d => d.IsST).ToList();
             return c;
         }).ToList();

Note that this will effect your original parents - I'm not sure that's a desirable outcome. 请注意,这会影响您的原父母-我不确定这是否是理想的结果。

The basic idea is to use SelectMany , but there are a couple wrinkles depending on assumptions. 基本思想是使用SelectMany ,但根据假设会有一些折衷

Basic code: 基本代码:

var list = parents.SelectMany
(
    p => p.ChildrenList.Where( c => c.IsST )
);

The above assumes there are 0 or 1 children per parent that match. 上面假设每个父母有0个或1个匹配的孩子。 If you want to handle the case where a parent has two or more matching children, you'll need one of the variants below. 如果您要处理父母有两个或多个匹配孩子的情况,则需要以下变体之一。

If you want to throw an exception if a parent has two or more children that match: 如果您的父母有两个或多个匹配的孩子,如果您想引发异常:

var list = parents.SelectMany
(
    p => p.ChildrenList.Single( c => c.IsST )
);

If you want to exclude parents that have two children that match: 如果要排除两个孩子匹配的父母:

var list = parents.SelectMany
(
    p => p.ChildrenList.SingleOrDefault( c => c.IsST )
    ??   Enumerable.Empty<Child>()
);

If you want to include the first child that matches: 如果要包括第一个匹配的子项:

var list = parents.SelectMany
(
    p => p.ChildrenList
          .Where( c => c.IsST )
          .Take(1)
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM