Le type 'Int32' a échoué parce que la valeur matérialisée est nulle

j'ai le code suivant. Je me trompe:

" le type 'Int32' a échoué parce que la valeur matérialisée est nulle. Soit le paramètre générique du type résultat, soit la requête doit utiliser un type nul."

lorsque la table CreditHistory n'a pas d'enregistrement.

var creditsSum = (from u in context.User
                  join ch in context.CreditHistory on u.ID equals ch.UserID                                        
                  where u.ID == userID
                  select ch.Amount).Sum();

Comment puis-je modifier la requête pour accepter des valeurs nulles?

170
demandé sur paqogomez 2011-07-28 23:05:24

7 réponses

une requête linq-to-sql n'est pas exécutée en tant que code, mais plutôt traduite en SQL. Parfois, il s'agit d'une" abstraction fuyante " qui produit un comportement inattendu.

un de ces cas est null handling, où il peut y avoir des null inattendues dans différents endroits. ...DefaultIfEmpty(0).Sum(0) peut aider dans ce cas (très simple), où il pourrait n'y avoir aucun élément et sql SUM retourne null alors que c# s'attend à 0.

Une approche plus générale est d'utiliser ?? qui sera traduit en COALESCE chaque fois qu'il y a un risque que le SQL généré renvoie un null inattendu:

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select (int?)ch.Amount).Sum() ?? 0;

ce premier caste int? pour dire au compilateur C# que cette expression peut en effet retourner null , même si Sum() renvoie un int . Ensuite, nous utilisons l'opérateur normal ?? pour gérer le cas null .

Basé sur cette réponse, j'ai écrit un blog post avec des détails à la fois pour LINQ à SQL et LINQ aux entités.

295
répondu Anders Abel 2012-08-08 15:11:49

pour permettre un champ nul Amount , il suffit d'utiliser l'opérateur nul pour convertir nulls à 0.

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch.Amount ?? 0).Sum();
8
répondu recursive 2011-07-28 19:08:02

vous utilisez la fonction aggregate qui ne reçoit pas les éléments pour effectuer l'action , vous devez vérifier que linq query donne un résultat comme ci-dessous:

var maxOrderLevel =sdv.Any()? sdv.Max(s => s.nOrderLevel):0
4
répondu Ashwini 2012-12-19 13:26:22

avait ce message d'erreur quand j'essayais de sélectionner à partir d'une vue.

le problème était que la vue avait récemment gagné de nouvelles lignes nulles (dans la colonne SubscriberId), et qu'elle n'avait pas été mise à jour dans EDMX (EF database first).

la colonne devait être de type nul pour qu'elle fonctionne.

var revendeur = Contexte.Concessionnaire.Où (x = > x.dealerCode = = dealerCode).FirstOrDefault ();

avant vue rafraîchir:

public int SubscriberId { get; set; }

Après actualisation de la vue:

public Nullable<int> SubscriberId { get; set; }

supprimer et ajouter la vue de nouveau dans EDMX travaillé.

J'espère que ça aidera quelqu'un.

4
répondu live-love 2017-06-26 20:34:40

j'utilise ce code et il répond correctement, seule la valeur de sortie est nulle.

var packesCount = await botContext.Sales.Where(s => s.CustomerId == cust.CustomerId && s.Validated)
                                .SumAsync(s => (int?)s.PackesCount);
                            if(packesCount != null)
                            {
                                // your code
                            }
                            else
                            {
                                // your code
                            }
1
répondu MohammadSoori 2017-03-20 07:25:53

je vois que cette question est déjà répondue. Mais si vous voulez qu'il soit divisé en deux énoncés, ce qui suit peut être considéré.

var credits = from u in context.User
              join ch in context.CreditHistory 
                  on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch;

var creditSum= credits.Sum(x => (int?)x.Amount) ?? 0;
1
répondu Lijo 2017-04-05 20:27:46

j'ai Obtenu cette erreur dans l'Entity Framework 6 avec ce code au moment de l'exécution:

var fileEventsSum = db.ImportInformations.Sum(x => x.FileEvents)

mise à jour de LeandroSoares:

utilisez ceci pour une exécution unique:

var fileEventsSum = db.ImportInformations.Sum(x => (int?)x.FileEvents) ?? 0

Origine:

changé à ceci et puis il a fonctionné:

var fileEventsSum = db.ImportInformations.Any() ? db.ImportInformations.Sum(x => x.FileEvents) : 0;
0
répondu Ogglas 2018-06-21 11:20:34