2 votes

System.Linq.Dynamic.Core : Comment faire un select many correctement ?

Je suis nouveau dans System.Linq.Dynamic.Core. J'ai ceci :

Disons que nous avons :

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

Je souhaite sélectionner le Packs avec Equipments mais dans les Equipments J'ai besoin d'avoir seulement celui avec Id=2 pour l'équipement générique (le résultat doit contenir une liste de paquets avec une liste d'équipements).

J'ai essayé :

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

mais j'ai l'impression d'être loin de mon objectif. Par ailleurs, existe-t-il une page de documentation sur l'utilisation de cette bibliothèque ?

Merci beaucoup

0voto

Ceux-ci devraient fonctionner :

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

0voto

Zev Spitz Points 2402

La version la plus récente de Dynamic LINQ semble être le projet aquí avec la documentation aquí .


En règle générale, la seule raison pour laquelle vous devriez préférer la méthode LINQ dynamique à la méthode LINQ standard est que les types sont no connu au moment de la compilation.

Si vous savez, au moment de la compilation, que la requête portera sur un fichier List<Pack> vous pouvez utiliser la méthode LINQ standard, comme dans le code suivant (notez que cela modifie les instances originales 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 originales, ce code crée des copies des instances originales :

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 qu'il ne s'agit pas d'utiliser .SelectMany - .SelectMany est utilisé pour créer un seul énumérable à partir d'énumérables imbriqués ; ici, chaque Pack dans la liste finale correspond à un Pack dans la liste originale.


Dynamic LINQ ne prend pas en charge la modification ou l'initialisation des propriétés dans le cadre de l'expression :

Le langage d'expression permet d'obtenir (mais pas de définir) la valeur de n'importe quel champ, propriété ou indexeur public accessible.

Ainsi, le Equipments ne peut pas être modifiée / initialisée pour n'inclure que des instances de Equipment qui correspondent aux critères.

Pour définir le Equipments Deux choix s'offrent à vous :

  1. Ajouter un constructeur à Pack qui prend les arguments appropriés
  2. Écrire une méthode statique sur n'importe quelle 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();
}

Vous pouvez alors utiliser la méthode suivante :

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 appeler :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X