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?
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.
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();
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
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.
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
}
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;
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;