从列表<T>的列表<T>中过滤

时间:2019-12-02 08:19:37

标签: c# linq lambda

我的关注基于我先前询问并得到解决的same question

起初我以为我得到了正确的答复,但是看到我没有。我的数据是这样的:

enter image description here

如果我这样过滤

var result = overdues.Where(a=>a.Accounts.Any(b=>b.AccountId.Equals("JKB2")));

我得到这样的结果:

enter image description here

但是我希望结果仅包含等于JKB2的帐户,而不包含等于JKB2的帐户。因此,我在这里强调的应该是结果,而不是其他:

enter image description here

从技术上讲,结果应该是这样的(我只是以JSON的形式编写了一个伪代码):

    [
    {
    Slab: T3,
    Value: 500,
    Percentage: 0
    Accounts: {
    AccountId:JKB2,
    AccountName:JKB2,
    SalesCode:JKB,
    Value:500
    }
    },
{
    Slab: T5,
    Value: 500,
    Percentage: 0
    Accounts: {
    AccountId:JKB2,
    AccountName:JKB2,
    SalesCode:JKB,
    Value:500
    }
    }
    ]

我的LinqPad工作在这里:

public class OverdueModel
    {
        public string Slab { get; set; }
        public double Value { get; set; }
        public double Percentage { get; set; }
        public List<OverdueSlabAccounts> Accounts { get; set; }
    }

    public class OverdueSlabAccounts
    {
        public string AccountId { get; set; }
        public string AccountName { get; set; }
        public string SalesCode { get; set; }
        public string Value { get; set; }
    }


void Main(){
    List<OverdueModel> overdues = new List<OverdueModel>();
    List<OverdueSlabAccounts> accounts1 = new List<OverdueSlabAccounts>();
    List<OverdueSlabAccounts> accounts2 = new List<OverdueSlabAccounts>();
    List<OverdueSlabAccounts> accounts3 = new List<OverdueSlabAccounts>();

    //For T3
    accounts1.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB1",
            AccountName = "JKB1",
            SalesCode = "JKB",
            Value = "500"
        });

    accounts1.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB2",
            AccountName = "JKB2",
            SalesCode = "JKB",
            Value = "500"
        });

    overdues.Add(new OverdueModel()
    {
        Slab = "T3",
        Value = 1000,
        Percentage = 0,
        Accounts= accounts1
    });

    //For T4
    accounts2.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB1",
            AccountName = "JKB1",
            SalesCode = "JKB",
            Value = "1000"
        });

    overdues.Add(new OverdueModel()
    {
        Slab = "T4",
        Value = 1000,
        Percentage = 0,
        Accounts= accounts2
    });

    //For T5
    accounts3.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB1",
            AccountName = "JKB1",
            SalesCode = "JKB",
            Value = "1000"
        });

    accounts3.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB2",
            AccountName = "JKB2",
            SalesCode = "JKB",
            Value = "500"
        });

    accounts3.Add(new OverdueSlabAccounts()
        {
            AccountId = "JKB3",
            AccountName = "JKB3",
            SalesCode = "JKB",
            Value = "500"
        });

    overdues.Add(new OverdueModel()
    {
        Slab = "T5",
        Value = 2000,
        Percentage = 0,
        Accounts= accounts3
    });

    //Show the Current Data
    overdues.Dump();

    var result = overdues.Where(a=>a.Accounts.Any(b=>b.AccountId.Equals("JKB2")));

    result.Dump();


}

2 个答案:

答案 0 :(得分:4)

此过滤器是正确的,因为它返回了具有记录的{ }实例; 问题是您只需要内部OverdueModel的过滤部分。如果假设我们不想更改所有对象,则需要为包含 那些已过滤帐户的新模型创建一个投影。也许像这样:

.Accounts

尽管有很多替代方案是可能的。例如,更扁平的模型将是:

var results = from outer in overdues
                where outer.Accounts.Any(b => b.AccountId == "JKB2")
                let filtered = outer.Accounts.FindAll(b => b.AccountId == "JKB2")
                select (Record: outer, Accounts: filtered);

答案 1 :(得分:1)

我相信您正在寻找的是LINQ中的SelectMany运算符,该运算符可将一系列的集合弄平。

所以请尝试以下

var result = overdues.SelectMany(a=>a.Accounts).Where(a=>a.AccountId.Equals("JKB2"))