我如何正确地选择许多

本文关键字:选择 许多 正确地 | 更新日期: 2023-09-27 18:17:33

我是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
                }
            }
        }
    }
}

我想选择EquipmentsPacks,但在选定的Equipments中,我需要只有具有Id=2的通用设备。(结果应包含设备清单和包装清单)。

我试过了:

querable.Where("Packs.Equipments.Select((GenericEquipment.Id)=1)");

但是我觉得我离题太远了。还有关于如何使用这个库的文档页面吗?

Thanks to lot

我如何正确地选择许多

动态LINQ的最新版本似乎是这里的项目,文档在这里。


一般来说,你需要动态LINQ而不是标准LINQ的唯一原因是当类型在编译时不知道时。

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

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. 在任何类上写一个静态方法,它接受适当的参数

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");

这些应该可以:

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链接(对不起,我在移动,所以我不能重命名它):https://msdn.microsoft.com/en-us/library/bb397927.aspx