2009-04-22 9 views
2

lors de l'exécution de la LINQ suivante pour instruction SQL:Pourquoi ai-je une exception InvalidOperationException avec cette méthode Linq to Sql?

var stuff = from l in _db.SqlLinks 
       select new 
          { 
           Link = l, 
           Rating = (from v in l.SqlLinkVotes 
             where v.Tag == tagId 
               && v.VoteDate >= since 
             select v.Vote).Sum(), 
           NumberOfVotes = (from v in l.SqlLinkVotes 
               where v.Tag == tagId 
                 && v.VoteDate >= since 
               select v.Vote).Count(), 
           NumberOfComments = (from v in l.SqlLinkVotes 
                where v.Tag == tagId 
                 && v.VoteDate >= since 
                 && v.Comment != "" 
                select v.Vote).Count() 
          }; 

Je reçois un System.InvalidOperationException (valeur nulle ne peut pas être attribué à Int32). Par le débogage, j'ai vu que cela vient de la propriété Rating de l'objet dynamique. Quand il n'y a pas de SqlLinkVotes pour un lien particulier, Sum() donne une valeur nulle, mais Rating est un int, et linq to sql pense que Sum() donnera un int, pas un intensible.

Je pourrais facilement écrire une procédure stockée pour contourner cela, mais j'ai pensé que c'était un bon moyen pour moi de mieux comprendre linq à sql.

Aidez s'il vous plaît!

Répondre

6

Il existe un Connect thread about this qui suggère que vous transtypiez le résultat de Sum() en un type Nullable (int? dans votre cas). Je suppose que si vous voulez que la note soit non annulable, vous pouvez alors utiliser l'opérateur null-coalescent:

Rating = ((int?) (from v in l.SqlLinkVotes 
        where v.Tag == tagId 
        && v.VoteDate >= 
        select v.Vote).Sum()) ?? 0 

Il vaut la peine d'essayer, de toute façon.

+0

Aha! Tu m'as battu! Je viens de poster la même chose. –

+0

Cette réponse fonctionne - a été mordu par cela il ya quelques semaines, a trouvé cette solution. –

+0

L'homme qui est un petit problème frustrant si –

0

On dirait que le simple fait de convertir le champ Rating en un intable NULL l'a corrigé.

Est-ce que cela semble raisonnable pour les autres?

var stuff = from l in _db.SqlLinks 
         select new 
            { 
             Link = l, 
             Rating = (int?)(from v in l.SqlLinkVotes 
               where v.Tag == tagId 
                 && v.VoteDate >= since 
               select v.Vote).Sum(), 
             NumberOfVotes = (from v in l.SqlLinkVotes 
                 where v.Tag == tagId 
                   && v.VoteDate >= since 
                 select v.Vote).Count(), 
             NumberOfComments = (from v in l.SqlLinkVotes 
                  where v.Tag == tagId 
                   && v.VoteDate >= since 
                   && v.Comment != "" 
                  select v.Vote).Count() 
            }; 
+0

Oui. Comme ma réponse le suggère, vous pouvez utiliser l'opérateur null-coalescing pour revenir à un formulaire non nullable en utilisant 0 comme valeur par défaut si vous le souhaitez. (J'espère * que ça marcherait, de toute façon ...) –

+0

C'est le cas, heureusement! Je transforme cet objet dynamique en un objet défini juste un peu plus bas dans la méthode, donc je remplace les valeurs nulles. –