Entity Framework appelant MAX sur null sur Records

entity-framework

Question

Lorsque j'appelle Max () sur un IQueryable et qu'il n'y a aucun enregistrement, j'obtiens l'exception suivante.

La conversion en type de valeur 'Int32' a échoué car la valeur matérialisée est null. Le paramètre générique du type de résultat ou la requête doit utiliser un type nullable.

var version = ctx.Entries
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId)
    .Max(e => e.Version);

Maintenant, je comprends pourquoi cela se produit. Ma question est de savoir quelle est la meilleure façon de procéder si le tableau peut être vide. Le code ci-dessous fonctionne et résout ce problème, mais il est très moche, n’y at-il pas de concept MaxOrDefault ()?

int? version = ctx.Entries
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId)
    .Select(e => (int?)e.Version)
    .Max();

Réponse acceptée

Oui, la conversion vers Nullable de T est la méthode recommandée pour traiter le problème dans les requêtes LINQ to Entities. Avoir une méthode MaxOrDefault () qui porte la bonne signature peut sembler une idée intéressante, mais vous auriez simplement besoin d'une version supplémentaire pour chaque méthode présentant ce problème, qui ne serait pas très évolutif.

C'est l'une des nombreuses incohérences entre la façon dont les choses fonctionnent dans le CLR et comment elles fonctionnent réellement sur un serveur de base de données. La signature de la méthode Max () a été définie de cette façon, car le type de résultat devrait être exactement le même que le type d'entrée sur le CLR. Mais sur un serveur de base de données, le résultat peut être nul. Pour cette raison, vous devez convertir l'entrée (bien que, selon la façon dont vous écrivez votre requête, il suffira peut-être de convertir le résultat) en Nullable de T.

Voici une solution qui semble légèrement plus simple que ce que vous avez ci-dessus:

var version = ctx.Entries 
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId) 
    .Max(e =>(int?)e.Version);

J'espère que cela t'aides.


Réponse populaire

Essayez ceci pour créer une valeur par défaut pour votre max.

int version = ctx.Entries 
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId) 
    .Max(e =>(int?)e.Version) ?? 0;


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow