La version la plus récente de Dynamic LINQ semble être le projet here, avec la documentation here.
En général, la seule raison pour laquelle vous devriez exiger dynamique LINQ sur LINQ est la norme quand les types sont pas connus au moment de la compilation.
Si vous connaissez au moment de la compilation que la requête sera contre un List<Pack>
, vous pouvez utiliser stanadard LINQ, comme dans le code suivant (notez que cela modifie les instances d'origine de Pack
):
var usefulPacks = Packs.Select(pack => {
pack.Equipments = pack.Equipments.Where(equipment =>
equipment.GenericEquipment.Id == 1
).ToList();
}).Where(pack => pack.Equipments.Any()).ToList();
Si vous avez besoin d'un code qui ne modifie pas les instances d'origine, ce code crée des copies des instances d'origine:
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();
Notez que ce n'utilise pas .SelectMany
— .SelectMany
est utilisé pour créer un seul énumérable à partir des énumératifs imbriqués; ici, chaque Pack
dans la liste finale correspond à Pack
dans la liste originale.
dynamique LINQ ne prend pas en charge la modification ou l'initialisation des propriétés dans le cadre de l'expression:
Le langage permet d'expression obtenir (mais pas de réglage) la valeur de tout champ public accessible, la propriété ou indexeur.
donc la propriété Equipments
ne peut être modifiée/initialisés pour inclure uniquement les instances de Equipment
qui correspondent aux critères.
Pour régler la Equipments
, vous avez deux choix:
- Ajouter un constructeur à
Pack
qui prend les arguments appropriés
- Ecrivez une méthode statique sur une classe qui prend les arguments appropriés
Ajouter un constructeur à Pack
Vous pouvez ajouter un constructeur à Pack
avec les arguments appropriés, qui définit Equipments
:
Pack(int IDAtSource, IEnumerable<Equipment> equipments) {
this.IDAtSource = IDAtSource;
this.Equipments = equipments.ToList();
}
Ensuite, vous pouvez utiliser les éléments suivants:
IQueryable qry = Packs.AsQueryable();
qry = qry
.Select("Pack(IDAtSource, Equipments.Where(GenericEquipment.ID=1))")
.Where("Equipments.Any");
Définir une méthode statique
public static class MyPackMethods {
public static Pack Create(int IDAtSource, IEnumerable<Equipment> equipments) {
return new Pack() {
IDAtSource = IDAtSource,
Equipments = equipments.ToList()
};
}
}
et appelez:
IQueryable qry = Packs.AsQueryable();
qry = qry
.Select("MyPackMethods.Create(IDAtSource, Equipments.Where(GenericEquipment.ID=1))")
.Where("Equipments.Any");
Merci beaucoup pour la réponse! En fait, cela répond presque à ma question. Quand j'ai fini la sélection, j'ai besoin du Pack, avec * juste * les équipements qui ont GenericEqipments avec Id = 1. Signification dans la liste des équipements un seul équipement devrait apparaître. Et aussi, je ne connais pas les types à l'exécution, c'était juste un exemple plus facile à donner comme ça. Merci encore, votre réponse est très utile. – Strawberry
@Strawberry C'est ce qui se passe dans la requête Dynamic LINQ. Nous appelons d'abord '.Select' qui crée une nouvelle instance de' Pack' pour chaque instance initiale de 'Pack', mais ne transmettent que le' Equipement' correspondant au constructeur de la nouvelle instance: 'Equipments.Where (GenericEquipment .ID = 1) '; alors nous appelons '.Where' pour n'inclure que des instances de' Pack' qui ont quelque chose dans la propriété 'Equipments'. –
Compris cher monsieur. Mais malheureusement, ce n'est pas une option pour changer le constructeur, donc je peux utiliser cette solution. – Strawberry