System.Linq.Dynamic.Core:如何正确选择多个?

时间:2016-11-12 20:24:24

标签: c# .net linq dynamic-linq

我是System.Linq.Dynamic.Core的新手。我有这个:

让我们说:

Packs = new List<Pack>
{
    new Pack()
    {
        IdAtSource="Pack1",
        Equipments= new List<Equipment>()
        {
            new Equipment
            {
                Id=1,
                GenericEquipment = new GenericEquipment()
                {
                    Id=7
                }
            }
        }
    },
    new Pack()
    {
        IdAtSource="Pack2",
        Equipments= new List<Equipment>()
        {
            new Equipment
            {
                Id=2,
                GenericEquipment = new GenericEquipment()
                {
                    Id=1
                }
            },
            new Equipment
            {
                Id=2,
                GenericEquipment = new GenericEquipment()
                {
                    Id=2
                }
            }
        }
    }
}

我想选择带Packs的{​​{1}},但在选定的Equipments中,我需要 Equipments对于通用设备。(结果应包含包含设备列表的包列表)。

我试过这个:

Id=2

但我觉得我在这里是目标。还有关于如何使用这个库的任何文档页面吗?

非常感谢

2 个答案:

答案 0 :(得分:0)

这些应该有效:

var equipments= from pack in Packs where pack.Equipments.Any() select pack.Equipments;

var secondEquipments = from pac in equipments where       
pac.GenericEquipment.Id == 2 select pac;
//I could use one variable instead of 2 but that would look a little bit complex

Msdn Link(对不起我在手机上,所以我无法重命名): https://msdn.microsoft.com/en-us/library/bb397927.aspx

答案 1 :(得分:0)

动态LINQ的最新版本似乎是项目here,文档为here

通常,您需要动态LINQ而不是标准LINQ的唯一原因是在编译时

如果您在编译时知道查询将针对List<Pack>,则可以使用stanadard LINQ,如下面的代码所示(请注意,这会修改Pack的原始实例):< / p>

var usefulPacks = Packs.Select(pack => {
    pack.Equipments = pack.Equipments.Where(equipment => 
        equipment.GenericEquipment.Id == 1
    ).ToList(); 
}).Where(pack => pack.Equipments.Any()).ToList();

如果您需要不修改原始实例的代码,则此代码会创建原始实例的副本:

var usefulPacks = Packs.Select(pack => {
    return new Pack() {
        IDAtSource = pack.IDAtSource,
        Equipments = pack.Equipments.Where(equipment => 
            equipment.GenericEquipment.Id == 1
        ).ToList(); 
    };
}).Where(pack => pack.Equipments.Any()).ToList();

请注意,这不是使用.SelectMany - .SelectMany用于从嵌套的枚举中创建单个可枚举;此处,最终列表中的每个Pack都对应于原始列表中的Pack

动态LINQ不支持在表达式中修改或初始化属性:

  

表达式语言允许获取(但不设置)任何可到达的公共字段,属性或索引器的值。

因此无法更改/初始化Equipments属性以仅包含符合条件的Equipment个实例。

要设置Equipments,您有两种选择:

  1. 将构造函数添加到Pack,其中包含适当的参数
  2. 在任何采用适当参数的类上编写静态方法
  3. 将构造函数添加到Pack

    您可以使用适当的参数向Pack添加构造函数,该参数设置Equipments

    Pack(int IDAtSource, IEnumerable<Equipment> equipments) {
        this.IDAtSource = IDAtSource;
        this.Equipments = equipments.ToList();
    }
    

    然后你可以使用以下内容:

    IQueryable qry = Packs.AsQueryable();
    qry = qry
        .Select("Pack(IDAtSource, Equipments.Where(GenericEquipment.ID=1))")
        .Where("Equipments.Any");
    

    定义静态方法

    public static class MyPackMethods {
        public static Pack Create(int IDAtSource, IEnumerable<Equipment> equipments) {
            return new Pack() {
                IDAtSource = IDAtSource,
                Equipments = equipments.ToList()
            };
        }
    }
    

    并致电:

    IQueryable qry = Packs.AsQueryable();
    qry = qry
        .Select("MyPackMethods.Create(IDAtSource, Equipments.Where(GenericEquipment.ID=1))")
        .Where("Equipments.Any");