System.Linq.Dynamic.Core :如何正确地使 select 多?
System.Linq.Dynamic.Core : How do I make a select many correctly?
我是 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
}
}
}
}
}
我想 select Packs
和 Equipments
,但是在 selected Equipments
我需要 只有 通用设备 Id=2
的那个。(结果应该包含带有设备列表的包列表)。
我试过这个:
querable.Where("Packs.Equipments.Select((GenericEquipment.Id)=1)");
但我觉得我没有达到目标。还有关于如何使用这个库的文档页面吗?
非常感谢
这些应该有效:
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
Dynamic LINQ 的最新版本似乎是项目 here, with the documentation here。
通常,您需要动态 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 不支持修改或初始化属性作为表达式的一部分:
The expression language permits getting (but not setting) the value of any reachable public field, property, or indexer.
因此 Equipments
属性 无法更改/初始化为仅包含符合条件的 Equipment
实例。
为了设置Equipments
,你有两个选择:
- 向
Pack
添加一个构造函数,它接受适当的参数
- 在任何 class 上编写一个静态方法,它接受适当的参数
添加构造函数到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");
我是 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
}
}
}
}
}
我想 select Packs
和 Equipments
,但是在 selected Equipments
我需要 只有 通用设备 Id=2
的那个。(结果应该包含带有设备列表的包列表)。
我试过这个:
querable.Where("Packs.Equipments.Select((GenericEquipment.Id)=1)");
但我觉得我没有达到目标。还有关于如何使用这个库的文档页面吗?
非常感谢
这些应该有效:
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
Dynamic LINQ 的最新版本似乎是项目 here, with the documentation here。
通常,您需要动态 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 不支持修改或初始化属性作为表达式的一部分:
The expression language permits getting (but not setting) the value of any reachable public field, property, or indexer.
因此 Equipments
属性 无法更改/初始化为仅包含符合条件的 Equipment
实例。
为了设置Equipments
,你有两个选择:
- 向
Pack
添加一个构造函数,它接受适当的参数 - 在任何 class 上编写一个静态方法,它接受适当的参数
添加构造函数到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");