使用linq按子集合的属性进行过滤

时间:2014-03-23 19:44:47

标签: c# linq

class Store
{
    public int ID { get; set; }
    public List<AnnualData> annualData { get; set; }
}

class AnnualData
{
    public int Year { get; set; }
    public Dictionary<string, double> Data { get; set; }
}

我需要获取所请求的商店和所请求年份的数据。我可以轻松过滤商店:

List<int> storeIDs = new List<int> {12, 13, 14};
List<Store> stores = allData.Stores.Where(s => storeIDs.Contains(s.ID)).ToList();

但我无法弄清楚如何按年列表进一步过滤。

List<int> years = new List<int> {2012, 2013, 2014};
stores = allData.Stores.Where(s => storeIDs.Contains(s.ID)).?????

尝试Any / All / Contains但我显然不太了解Linq。提前谢谢。

Selmann&amp; amp;提出的解决方案后更新蒂莫西 使用你的例子我仍然可以看到输出中存储1的所有3年 - 我想在他的情况下只看到2007年:

   static void Main(string[] args)
    {
        List<Store> allData = new List<Store> {                 
            new Store { ID = 1,
                        annualData = new List<AnnualData> {
                            new AnnualData {
                                Year = 2006,
                                Data = new Dictionary<string, double>{{"Value2006", 1.0}}
                            },
                            new AnnualData {
                                Year = 2007,
                                Data = new Dictionary<string, double>{{"Value2007", 1.1}}
                            },
                            new AnnualData {
                                Year = 2008,
                                Data = new Dictionary<string, double>{{"Value2008", 1.2}}
                            }
                        }
            }
        };

        List<int> storeIDs = new List<int> { 1 };
        List<int> years = new List<int> { 2007 };

        var stores = allData.Where(s => storeIDs.Contains(s.ID) &&
                                     s.annualData.Any(x => years.Contains(x.Year)));

        foreach (Store s in stores)
            foreach (AnnualData a in s.annualData)
                Console.WriteLine(a.Year);

    }

3 个答案:

答案 0 :(得分:3)

您可以使用Any方法:

stores = allData.Stores.Where(s => storeIDs.Contains(s.ID) && 
                                 s.annualData.Any(x => years.Contains(x.Year)));

答案 1 :(得分:1)

stores = allData.Stores
    .Where(s => storeIDs.Contains(s.ID))
    .Select(s => new Store
    {
        ID = s.ID,
        annualData = s.annualData
            .Where(x => years.Contains(x.Year))
            .ToList()
    });

答案 2 :(得分:1)

您无法选择Store对象,其中AnnualData个对象的列表仅包括年份为2007的对象,因为不存在此类对象。您获得所有年份的原因是因为您选择了一个Store对象,其中列表中的任何AnnualData个对象都具有2007年 - 但它仍然会返回整个列表。

要获得Store只包含您想要的AnnualData项目的列表,您需要创建它...

var stores = allData.Where(s => storeIDs.Contains(s.ID))
                    .Select(s =>
                        new Store { ID = s.ID, annualData = s.annualData.Where(x => years.Any(y => y == x.Year)).ToList() } )
                    .ToList();