2010-01-21 4 views
2

Ma requête ressemble à ceci:LINQ à chaîne SQL joignant à une valeur null

var products = from p in Products 
       select new 
       { 
        ProductId = p.ProductId, 
        Description = p.Quantity + " x " p.Price + ", " + p.ItemDescription 
       }; 

La raison pour laquelle je joinin la description dans la requête, est que je fais cela pour plusieurs Interroge/objets, pour créer un écran d'historique (un peu comme un écran d'audit). L'écran prend un certain temps pour se charger, alors je prends tous de la requête et de faire une

products.Concat(otherProducts); 

La vitesse a considérablement augmenté (2-3 minutes jusqu'à 2-3 secondes), cependant, si dans l'exemple , p.ItemDescription (qui est un VARCHAR (50) dans la base de données) est null, mais la quantité et le prix ne sont pas nuls, alors tout le champ Description devient null.

Est-ce que quelqu'un a rencontré cette anomalie? Quelqu'un sait-il comment l'afficher "4 x 5,99" au lieu de simplement le mettre à zéro?

Toute aide serait appréciée, j'ai essayé de contourner cela un peu, et je ne sais même pas comment vraiment chercher sur google.

+0

êtes-vous sûr qu'il est LINQ to SQL ou LINQ-objet? –

+0

@asdi: LINQ-to-objects lève une exception. –

Répondre

6

Ce n'est pas un «quirk» LINQ-to-SQL, c'est un comportement SQL standard.

Si j'ai l'expression:

columnA + columnB + columnC 

Et l'une de ces colonnes sont null, l'expression entière sera évaluée comme null.

Vous souhaitez fusionner les valeurs nulles en chaînes vides. Essayez ceci:

select new 
      { 
       ProductId = p.ProductId, 
       Description = p.Quantity + " x " + 
          p.Price + ", " + 
          (p.ItemDescription ?? "") 
      } 
2

En termes de sql concaténant null avec toute autre valeur se traduit par null.

Donc, vous avez deux choix. D'abord (et c'est ainsi que j'irais), modifiez le champ ItemDescription de votre table pour qu'il ne soit pas Nullable. Définir une valeur par défaut de quelque chose comme '' (vide). Le problème s'en va.

Deuxième option, modifiez votre code linq pour fusionner le champ ItemDescription afin d'émettre un blanc si la valeur sous-jacente est null. Je ne suis pas un gars linq, donc je ne sais pas comment faire ça. L'un des problèmes avec la deuxième route est qu'elle devrait exécuter la fonction coalesce pour chaque enregistrement dans l'ensemble de résultats des produits, ce qui pourrait avoir un impact négatif sur les performances.

2

Ce n'est pas une bizarrerie, ce comportement est par défaut sur le serveur SQL (vous pouvez utiliser SET CONCAT_NULL_YIELDS_NULL ON|OFF sur la connexion pour activer ou désactiver).

Vous devriez être en mesure d'utiliser quelque chose comme ça pour la contourner:

var products = from p in Products 
       select new 
       { 
        ProductId = p.ProductId, 
        Description = p.Quantity + " x " p.Price + ", " + (p.ItemDescription ?? "") 
       }; 
0

Essayez:

select new 
      { 
       ProductId = p.ProductId, 
       Description = string.Format(
          "{0} x {1}, {2}", 
          p.Quantity, 
          p.Price, 
          p.ItemDescription) 
      }