2010-07-05 10 views
7

J'ai la requête linq ci-dessous qui prend un champ de texte qui peut être Y, N ou DBnull et remplit un booléen? paramètre avec True, False ou null en fonction de la valeur du champ.C# utilisant LINQ et Nullable Boolean

var dset = from i in tbdc.Talkbacks 
     where i.talkback_id == id 
     select new Talkback(
       i.talkback_id, i.acad_period, i.reference, 
       i.staff_member, i.date_received, i.no_talkers, 
       i.gender_id, i.names, i.type_id, 
       i.method_id, i.area_id, i.site_id, 
       i.category_id, i.date_closed, i.expenddate, 
       i.acknowledgementtarget, 
       (i.targetmet == "Y") ? true : 
        ((i.targetmet == "N") ? false : null), 
        (i.acknowledgementtargetmet != "N") ? true : false 

La ligne problématique est

(i.targetmet == "Y") ? true : ((i.targetmet == "N") ? false : null) 

Après avoir lu j'ai trouvé une documentation qui précise que les arguments de 2e et 3e de la ligne si besoin d'être du même type ou être implicitement convertible en un un autre.

Ma question est, comment puis-je contourner cette limitation pour atteindre mon résultat souhaité? Je suis relativement nouveau à C# donc je ne suis pas familier avec toutes ses bizarreries/capacités pour le moment.

Répondre

6

Ma suggestion serait de le remplacer par:

(i.targetmet != null) ? (bool?)(i.targetmet == "Y") : null; 

la raison pour laquelle le compilateur ne sont pas d'accord sans la distribution est celle-là même si vous la stockez dans une structure nullable, l'opération ternaire vérifie si les résultats sont compatibles par une conversion implicite.

Résultats true et false sont traités comme bool littéraux, non bool?, convertible donc pas implicitement null. Casting soit les résultats à bool? les rendra comparables. Celui que je suggère a une convertion implicite entre bool? et null, et cela fonctionne aussi:

(i.targetmet != null) ? (i.targetmet == "Y") : (bool?)null; 

Ce qui est une conversion implicite entre un bool et bool?. Je préfère arbitrairement le premier ..

+0

Cela a fonctionné très bien. Je reçois maintenant un problème plus loin dans la ligne où j'essaie d'utiliser la valeur dans un DisplayTemplate avec le code ci-dessous: <% @ Control Language = "C#" Inherits = "System.Web.Mvc.ViewUserControl "%> <%: ((Booléen?) Modèle.Valeur == Vrai)? "kpi_tick.png": "kpi_cross.png"%> L'idée est qu'elle affichera une image de graduation pour true, une image croisée pour false et pas d'image pour undefined (n'a pas encore fait ce bit du code) . Je reçois l'erreur "Le nom 'True' n'existe pas dans le contexte actuel" – hermiod

+2

Ce balisage ressemble à ASP.NET, avec lequel j'ai beaucoup travaillé dernièrement. Tellement tiré au hasard dans l'obscurité: remplacer True par vrai? –

+0

Créez une classe statique appelée BoolHelper avec une méthode statique bool Parse (string s) qui contient la solution de Dynami. Ensuite, utilisez cela pour simplifier les choses pour votre analyseur. –

2

Vous pouvez convertir explicitement un ou plusieurs des expressions à un bool?:

(i.targetmet == "Y") ? true : ((i.targetmet == "N") ? (bool?)false : (bool?)null)