0
votes

Instruction LINQ utilisant l'un des deux paramètres

Je travaille sur une instruction LINQ. J'ai une table de villes où les enregistrements ont un countryId ou un stateId . Je voudrais simplement écrire une instruction et faire vérifier la clause where pour voir lequel des deux paramètres est nul, puis sélectionner celui qui ne l'est pas.

Voici ce avec quoi je travaille:

public List<City> Cities(int? countryTypeId, int? stateTypeId)
{
    if (countryTypeId == null && stateTypeId == null) 
        return null;

    return _db.City
        .Where(x => x.StateTypeId == stateTypeId
                    && x.CountryTypeId == countryTypeId)
        .OrderBy(x => x.Description)
        .ToDTOs();
}

Je suis assez nouveau sur LINQ, et je sais que ce code n'est pas correct, il suffit de l'ajouter pour le contexte.


3 commentaires

Ce n'est pas vraiment une question linq; c'est une question logique booléenne: Où (x => (! stateTypeId.HasValue || stateTypeId.Value == x.StateTypeId) && (! countryTypeId.HasValue || countryTypeId.Value == x.CountryTypeId)) . Avec l'évaluation des courts-circuits, lorsque stateTypeId n'a pas de valeur, cette sous-expression est toujours true . Si les deux paramètres sont nuls, les deux sous-expressions sont toujours vraies et la requête renvoie tout.


@EdPlunkett Lorsque vous traitez avec LINQ to SQL / EF, je pense qu'il est juste de dire que c'est une question LINQ - toute solution suggérée doit avoir une traduction SQL. ( HasValue est traduit par LINQ en SQL.)


Vouliez-vous vérifier si les paramètres sont nuls ou si les champs de la base de données sont nuls ou les deux?


3 Réponses :


1
votes

Si les identifiants State et Country sont tous > 0 , vous pouvez simplement le faire, inutile de vérifier la valeur nulle

Where(x => (stateTypeId.HasValue && stateTypeId.Value == x.StateTypeId) 
     || (countryTypeId.HasValue && countryTypeId.Value == x.CountryTypeId))

Sinon, vous devez ajouter la condition si ces entrées nullables ont une valeur ou non, comme mentionné dans le commentaire

Modifier: après avoir vu quelques commentaires, si vous recherchez une liste de villes en fonction de l'un ou l'autre des paramètres, alors vous devriez utiliser || et non && dans votre condition où

 .Where(x => x.StateTypeId == stateTypeId.GetValueOrDefault()
                    && x.CountryTypeId == countryTypeId.GetValueOrDefault())


9 commentaires

C'est la partie x.StateTypeId qui est Nullable<> , car il s'agit d'un champ de base de données.


@NetMage, peu importe qu'il soit nullable sur db ou non, ce sont les paramètres qu'il vérifie. Regardez la question avant de donner des réponses négatives. Et s'il est nullable dans db, linq peut facilement le gérer sans aucune validation


@EdPlunkett Pas ma question.


Cela semble évident d'après le texte réel: "où les enregistrements ont soit un countryId ou un stateId "


@NetMage Alors, comment êtes-vous certain que ces colonnes peuvent être nulles?


@EdPlunkett J'ai lu la question, bien que je concède que le reste du paragraphe rend la question réelle ambiguë.


@NetMage Vous n'avez pas écrit la question. Vous avez peut-être bien deviné, cependant.


@NetMage, si les colonnes sont nullables dans db, linq peut le gérer sans aucune validation de contrôle nul, et ce n'est pas ce qu'il demandait. Merci.


@NetMage, je vois ton point, j'ai mis à jour la réponse, la question est un peu vague



0
votes
_db.City.Where(c => (c.CountryTypeId ?? c.StateTypeId) == (countryTypeId ?? stateTypeId))

0 commentaires

0
votes

Mon DBA m'a suffisamment inséré dans la tête que le fait d'ignorer les paramètres dans une requête (ex: WHERE Field = @PARAM ou @PARAM IS NULL) peut entraîner de très mauvaises choses. Par conséquent, je vous encourage à n'ajouter conditionnellement que les paramètres dont vous avez absolument besoin. Heureusement, étant donné que vous ne travaillez qu'avec deux paramètres possibles, c'est trivial.

Commencez par la base de votre requête, puis ajoutez-y.

var queryBase = _db.City.OrderBy(x => x.Description);

if (countryTypeId.HasValue)
{
    queryBase = queryBase.Where(x => x.CountryTypeId == countryTypeId);
}

if (stateTypeId.HasValue)
{
    queryBase = queryBase.Where(x => x.StateTypeId == stateTypeId);
}

return queryBase.ToDTOs(); // or .ToList() for a more universal outcome

Ajoutez la logique dont vous pourriez avoir besoin si les paramètres sont mutuellement exclusifs, l'un remplace l'autre, etc.


0 commentaires