如何使用LINQ C#过滤内部集合

3
我需要使用LINQ过滤集合的内部集合以获取记录。
public class MobileModel : Notify
{
    private string _brand = string.Empty;
    private ObservableCollection<MobileModelInfo> _model = new ObservableCollection<MobileModelInfo>();
    private string _os = string.Empty;

    public string Brand
    {
        get { return _brand; }
        set { _brand = value; OnPropertyChanged(); }
    }
    public ObservableCollection<MobileModelInfo> Model
    {
        get { return _model; }
        set { _model = value; OnPropertyChanged(); }
    }

    public string OS
    {
        get { return _os; }
        set { _os = value; OnPropertyChanged(); }
    }
}

public class MobileModelInfo
{
    public string Name { get; set; }
    public string Catagory { get; set; }
    public string Year { get; set; }
}


public void GetMobile()
    {
        List<MobileModel> mList = new List<MobileModel>();
        List<MobileModelInfo> modList = new List<MobileModelInfo>();
        MobileModel mob = new MobileModel();

        modList.Clear();
        mob.Brand = "Apple";
        modList.Add(new MobileModelInfo { Name = "iPhone 4", Catagory = "Smart Phone", Year = "2011" });
        modList.Add(new MobileModelInfo { Name = "iPhone 5", Catagory = "Smart Phone", Year = "2013" });
        modList.Add(new MobileModelInfo { Name = "iPhone 6", Catagory = "Premium Smart Phone", Year = "2015" });
        mob.Model = new ObservableCollection<MobileModelInfo>(modList);
        mob.OS = "IOS";
        mList.Add(mob);

        mob = new MobileModel();
        modList.Clear();
        mob.Brand = "Samsung";
        modList.Add(new MobileModelInfo { Name = "S4", Catagory = "Smart Phone", Year = "2011" });
        modList.Add(new MobileModelInfo { Name = "S5", Catagory = "Smart Phone", Year = "2013" });
        modList.Add(new MobileModelInfo { Name = "S6", Catagory = "Ultra Smart Phone", Year = "2015" });
        mob.Model = new ObservableCollection<MobileModelInfo>(modList);
        mob.OS = "Android";
        mList.Add(mob);

        mob = new MobileModel();
        modList.Clear();
        mob.Brand = "MicroSoft";
        modList.Add(new MobileModelInfo { Name = "Lumina 9900", Catagory = "Phone", Year = "2011" });
        modList.Add(new MobileModelInfo { Name = "Opera X220", Catagory = "Smart Phone", Year = "2013" });
        mob.Model = new ObservableCollection<MobileModelInfo>(modList);
        mob.OS = "Windows";
        mList.Add(mob);

        mob = new MobileModel();
        modList.Clear();
        mob.Brand = "Sony Ericssion";
        modList.Add(new MobileModelInfo { Name = "S4", Catagory = "Smart Phone", Year = "2011" });
        modList.Add(new MobileModelInfo { Name = "S5", Catagory = "Smart Phone", Year = "2013" });
        modList.Add(new MobileModelInfo { Name = "S6", Catagory = "Ultra Smart Phone", Year = "2015" });
        mob.Model = new ObservableCollection<MobileModelInfo>(modList);
        mob.OS = "Android";
        mList.Add(mob);

        MobileList = new ObservableCollection<MobileModel>(mList);
    }

ObservableCollection MobileList有三个属性:品牌、型号和操作系统。其中,型号属性又是一个ObservableCollection,在MobileModelInfo类中有三个属性:名称、类别和年份。

我需要这个集合包含内部集合MobileModelInfo中的2011年。其余记录不需要。

在三星中,它应该只包含

mob.Brand = "Samsung";
modList.Add(new MobileModelInfo { Name = "S4", Catagory = "Smart Phone", Year = "2011" });
mob.OS = "Android";

实际初始输出屏幕截图为 Original List without Filter

期望的输出结果是 After Filter


如果不使用LINQ,你可以遍历模型项并获取列表。 - Vini
3个回答

6

使用 SelectMany() :

MobileList.SelectMany(x => x.Model).Where(m=>m.Year==2011)

意思是在移动设备列表中选择所有型号,然后筛选出年份为2011年的型号。

请在MobileList属性中使用LINQ,而不是mList。 - B.Balamanigandan
外部集合属性丢失。我们需要排除年份不等于2011的情况。但是您的LINQ结果只有MobileModelInfo集合而不是MobileModel。 - B.Balamanigandan
我认为这可能会有帮助 MobileList.Where(x => x.Model.Any(m=>m.Year==2011)) - Gurgen Sargsyan

4
var filtered = MobileList.Select(m => new MobileModel {
                Model = new ObservableCollection(m.Model.Where(model => model.Year == "2011").ToList()),
                Brand = m.Brand,
                OS = m.OS
            })

;


我遇到了一个错误2,无法隐式转换类型'System.Collections.Generic.List<DataGridInWPF.MobileModelInfo>'为'System.Collections.ObjectModel.ObservableCollection<DataGridInWPF.MobileModelInfo>'。 - B.Balamanigandan
我改进了我的答案,使用ObservableCollection。 - Oleg Golovkov
它返回了属性品牌和操作系统为空。 - B.Balamanigandan
哦,我明白了,你只需要复制那些内容,查看我的更新答案。 - Oleg Golovkov

2
我认为你可以使用内部 where 条件来解决这个问题。请检查以下内容:
   var result = MobileList.Where(m => m.Model.Where(mdl => mdl.Year =="2011")).ToList();

在where条件中,我们应该给出布尔表达式而不是内部where。这将会产生编译时错误。 - B.Balamanigandan
1
也许应该使用 any 而不是 where,就像这样 'MobileList.Where(m => m.Model.Any(mdl => mdl.Year =="2011")).ToList();'。但很抱歉我无法尝试这些答案。 - Alper Tunga Arslan
我怀疑它是否能够编译。 - rahulaga-msft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接