2017-04-19 1 views
1

Si j'exécute ma proc stockée à partir de SSMS, je peux voir clairement un 1 dans la colonne en question (qui devrait retourner true dans ADO) , mais quand dans mon milieu, le DataReader retourne toujours false. Je craignais que cela puisse être parce que je suis la valeur bit dans mon instruction SELECT, mais si je change l'instruction CASE pour être juste CAST(1 AS BIT) le DataReader lit correctement tout comme true, donc ce n'est pas le casting. [Pointe du chapeau à @MikhailLobanov pour cette]ADO.NET - Valeur de bit SQL "1" toujours lue comme "false" par DataReader

Voici mon script SQL:

SELECT CASE 
    WHEN receiptid IS NULL THEN CAST(0 AS BIT) 
    ELSE CAST(1 AS BIT) 
END [WasAdjusted] 
FROM dbo.MyTable 

UNION ALL 

SELECT CONVERT(BIT, 0) [WasAdjusted] 
FROM dbo.MySecondTable 

Alors voici mon ADO.NET code C#:

Func<IDataRecord, ResponseModel> searchReader = delegate (IDataRecord record) 
{ 
    var model = new ResponseModel(); 
    model.BooleanProperty = record.GetBoolean(0);  
    return model; 
}; 

Quelqu'un a demandé le code environnant, est donc ici mon DataReader:

protected static List<TReturnType> ExecuteReader<TReturnType>(string connectionString, string storedProcName, Func<IDataRecord, TReturnType> delegateFunction, List<SqlParameter> collection = null) 
{ 
    List<TReturnType> results = null; 

    try 
    { 
     using (SqlConnection connect = new SqlConnection(connectionString)) 
     { 
      connect.Open(); 

      SqlCommand command = new SqlCommand(storedProcName, connect); 
      command.CommandTimeout = 1000; 
      command.CommandType = CommandType.StoredProcedure; 

      if (collection != null) 
      { 
       collection.ForEach(x => command.Parameters.Add(x)); 
      } 

      using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection)) 
      { 
       while (reader.Read()) 
       { 
        if (results == null) 
        { 
         results = new List<TReturnType>(); 
        } 

        results.Add(delegateFunction((IDataRecord)reader)); 
       } 

       reader.Close(); 
      } 

      connect.Dispose(); 
     } 
    } 
    catch (Exception ex) 
    { 
     throw new Exception(ex.Message); 
    } 

    return results; 
} 

Ensuite, vous appelez ça comme ceci:

return ExecuteReader(_connectionString, "dbo.NameOfStoredProc", searchReader, sqlParams); 

Que manque-t-il? Merci.

Modifier 25/04/2017: On dirait que quelqu'un d'autre peut-être avoir même question: https://github.com/AutoMapper/AutoMapper.Data/issues/12

+0

Peut-être que vous avez besoin de nommer votre colonne (donner un alias à la colonne)? – Shnugo

+0

@Shnugo le nom de ma colonne (FWIW) est 'WasAdjusted'. J'ai essayé de faire 'record.GetBoolean (record.GetOrdinal (" WasAdjusted "))', mais cela me donne le même résultat. Je vais mettre à jour ma question pour montrer. – codeMonkey

+1

pourquoi devriez-vous jeter de la valeur en tant que peu? vous avez juste besoin de deux valeurs différentes, pourquoi ne pas simplement retourner quelque chose comme 'T'/'F', et record.GetString (0) –

Répondre

2

Assurez-vous que l'utilisateur exécutant la procédure stockée a les mêmes autorisations/égales. Il est possible que l'utilisateur de l'application (exécutant le IDataReader) ait des autorisations différentes du compte que vous utilisez personnellement pour vous connecter à SSMS, auquel cas le même proc stocké fournirait deux ensembles de résultats différents.

0

La méthode IDataRecord.GetBoolean prévoit que la valeur est déjà une valeur booléenne. Il ne tentera pas de le convertir. Vous pouvez utiliser le code suivant pour obtenir la valeur booléenne: Convert.ToBoolean(record.GetValue(record.GetOrdinal("WasAdjusted")))

+0

Le problème est 'record.GetValue (record.GetOrdinal (" WasAdjusted "))' retourne 'false' quand il devrait être' true', pas qu'il ne puisse reconnaître un booléen. – codeMonkey