2 votes

Requête LINQ pour vérifier si un seul combo existe dans une liste de combos

Utilisation de EF Core 3.x

J'essaie de vérifier si une table de la base de données, Ducks contient déjà tous les enregistrements dont la combinaison de valeurs correspond, à partir d'une liste de valeurs combinées, stockée dans une classe : Duck .

Je m'attends à ce que l'on me renvoie l'information suivante Duck.Id des enregistrements qui existent déjà / qui ont les valeurs correspondantes que je transmets.

Pour l'instant, je ne peux que vérifier si un seul combo existe à la fois en utilisant la requête suivante

La combinaison ici est 1, "NV", et "Mallard". Le résultat est le suivant true

var duckExists = Ducks
    .Any(duck =>
        duck.PondId == 1 &&
        duck.StateId == "NV" &&
        duck.Type == "Mallard");

Je souhaite maintenant vérifier si plusieurs Ducks existe déjà.
J'ai une liste, ducksToCheck que je souhaite utiliser pour interroger la base de données afin de vérifier si l'un d'entre eux existe déjà :

var ducksToCheck = new List<Duck>() {
    // Does exist
    new Duck{
        PondId = 1,
        State = "NV",
        Breed = "Mallard"
    },
    // Does exist
    new Duck{
        PondId = 2,
        State = "AZ",
        Breed = "Crested"
    },
    // Does not exist
    new Duck{
        PondId = 1,
        State = "AZ",
        Breed = "Crested"
    },
    // Does not exist
    new Duck{
        PondId = 2,
        State = "NV",
        Breed = "Mallard"
    }
};

Ma dernière tentative a consisté à placer chaque valeur unique de la combinaison dans sa propre liste et à la comparer à ces listes dans la requête.
Cela ne fonctionne pas car tant qu'un Duck a une valeur correspondante dans chaque liste, il est perçu comme existant alors qu'il n'existe pas.
Par exemple, le troisième canard : (1, "AZ", "Crested"). Puisque le SQL résultant est duck.PondId IN(pondIds) && duck.State IN(states) && duck.Breed IN(breeds) les deux premiers canards ont un mélange de ces valeurs et il peut les mélanger pour dire qu'il existe.

var pondIds = ducksToCheck.Select(x => x.PondId).Distinct().ToList();
var states = ducksToCheck.Select(x => x.State).Distinct().ToList();
var breeds = ducksToCheck.Select(x => x.Breed).Distinct().ToList();

var existingDuckIds = Ducks
    .Where(duck => pondIds
        .Any(pondId => pondId == duck.pondId)
            && states.Any(state => state == duck.State)
            && breeds.Any(breed => breed == duck.Breed)
    )
    .Select(duck => duck.Id);

Est-il possible de demander si une combinaison unique existe dans le fichier Ducks à partir d'une liste de combinaisons, sans envoyer de requête pour chaque combinaison individuelle / Duck en ducksToCheck ?

0voto

CsharpDev Points 46

/!\NTravail uniquement pour les données évaluées

Sur votre objet Modèle, vous pouvez implémenter l'interface IEquatable, en ajoutant votre script égal sur la méthode Equals, comme :

public bool Equals([AllowNull] Duck other)
{
    return other.Id == ID; // add other conditions
}

Et l'appeler :

var result = Ducks.Any(x => ducksToCheck.Contains(x));

Si vous ne souhaitez pas modifier votre modèle de base de données, vous pouvez ajouter une nouvelle méthode de vérification :

private bool Check(Duck x, List<Duck> filterDucks)
{
    foreach (var filterDuck in filterDucks)
    {
        if (filterBook.Title == x.Title)
            return true;
        else
            continue;
    }
    return false;
}

Et l'appeler :

var result = Ducks.Where(x => Check(x ,ducksToCheck));

Bonne chance,

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