I am new to the System.Linq.Dynamic.Core. I have this:
Let's say we have:
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
}
}
}
}
}
I would like to select the Packs
with Equipments
, but in the selected Equipments
I need to have only the one with Id=2
for Generic Equipment.(the result should contain a list of packs with list of equipments).
I've tried this:
querable.Where("Packs.Equipments.Select((GenericEquipment.Id)=1)");
but I feel I am waaay of target here. Also is there any documentation page on how to use this library?
Thanks a lot
The most recent version of Dynamic LINQ appears to be the project here, with the documentation here.
Generally, the only reason why you should require Dynamic LINQ over standard LINQ is when the types are not known at compile time.
If you know at compile time that the query will be against a List<Pack>
, you can use stanadard LINQ, as in the following code (note that this modifies the original instances of Pack
):
var usefulPacks = Packs.Select(pack => {
pack.Equipments = pack.Equipments.Where(equipment =>
equipment.GenericEquipment.Id == 1
).ToList();
}).Where(pack => pack.Equipments.Any()).ToList();
If you need code that doesn't modify the original instances, this code creates copies of the original instances:
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();
Note that this isn't using .SelectMany
— .SelectMany
is used to create a single enumerable from nested enumerables; here each Pack
in the final list corresponds to a Pack
in the original list.
Dynamic LINQ doesn't support modifying or initializing properties as part of the expression:
The expression language permits getting (but not setting) the value of any reachable public field, property, or indexer.
so the Equipments
property cannot be changed / initialized to include only instances of Equipment
that match the criteria.
In order to set the Equipments
, you have two choices:
Pack
which takes the appropriate arguments Add a constructor to Pack
You can add a constructor to Pack
with the appropriate arguments, that sets Equipments
:
Pack(int IDAtSource, IEnumerable<Equipment> equipments) {
this.IDAtSource = IDAtSource;
this.Equipments = equipments.ToList();
}
Then you could use the following:
IQueryable qry = Packs.AsQueryable();
qry = qry
.Select("Pack(IDAtSource, Equipments.Where(GenericEquipment.ID=1))")
.Where("Equipments.Any");
Define a static method
public static class MyPackMethods {
public static Pack Create(int IDAtSource, IEnumerable<Equipment> equipments) {
return new Pack() {
IDAtSource = IDAtSource,
Equipments = equipments.ToList()
};
}
}
and call:
IQueryable qry = Packs.AsQueryable();
qry = qry
.Select("MyPackMethods.Create(IDAtSource, Equipments.Where(GenericEquipment.ID=1))")
.Where("Equipments.Any");
These should work:
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(Sorry I'm at mobile so I can't rename it): https://msdn.microsoft.com/en-us/library/bb397927.aspx