J'ai le code suivant. Je reçois une erreur:
"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."
lorsque la table CreditHistory ne contient aucun 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 les valeurs NULL?
Une requête linq-to-sql n'est pas exécutée sous forme de code, mais traduite en SQL. Parfois, il s'agit d'une "abstraction qui fuit" qui donne un comportement inattendu.
Un de ces cas est la gestion des valeurs NULL, où il peut y avoir des valeurs NULL inattendues à différents endroits. ...DefaultIfEmpty(0).Sum(0)
peut aider dans ce cas (assez simple), où il pourrait ne pas y avoir d'éléments et où SUM
de SQL retournera null
alors que c # s'attend à 0.
Une approche plus générale consiste à utiliser ??
qui sera traduit en COALESCE
chaque fois que le SQL généré risque de renvoyer une valeur NULL inattendue:
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;
Cela lance d'abord int?
pour indiquer au compilateur C # que cette expression peut en effet renvoyer null
, même si Sum()
renvoie un int
. Nous utilisons ensuite l’opérateur normal ??
pour gérer le cas null
.
Sur la base de cette réponse, j'ai écrit un article de blog avec des détails pour LINQ to SQL et LINQ to Entities.
Pour autoriser un champ nullable Amount
, il suffit d'utiliser l'opérateur de fusion nul pour convertir les valeurs nulles en 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 nécessite pas que les éléments effectuent une action, vous devez vérifier que la requête linq donne un résultat comme ci-dessous:
var maxOrderLevel =sdv.Any()? sdv.Max(s => s.nOrderLevel):0
Vous aviez ce message d'erreur lorsque j'essayais de sélectionner 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 (base de données EF en premier).
La colonne devait être de type Nullable pour fonctionner.
var dealer = Context.Dealers.Where (x => x.dealerCode == dealerCode) .FirstOrDefault ();
Avant de rafraîchir la vue:
public int SubscriberId { get; set; }
Après le rafraîchissement de la vue:
public Nullable<int> SubscriberId { get; set; }
La suppression et l'ajout de la vue dans EDMX ont fonctionné.
J'espère que ça aide quelqu'un.
J'ai utilisé ce code et il répond correctement, seule la valeur de sortie est nullable.
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 souhaitez le scinder en deux déclarations, les suivantes peuvent être considérées.
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;
Vous avez cette erreur dans 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
Original:
Changé pour cela et puis ça a fonctionné:
var fileEventsSum = db.ImportInformations.Any() ? db.ImportInformations.Sum(x => x.FileEvents) : 0;