web-dev-qa-db-fra.com

Renvoyer une seule ligne

J'essaie de renvoyer une seule ligne d'une base de données:

using (connection = new SqlConnection(ConfigurationManager.AppSettings["connection"]))
{
    using (command = new SqlCommand(@"select top 1 col_1, col_2 from table1", connection))
    {
        connection.Open();

        using (reader = command.ExecuteReader())
        {
            reader.Read();
            return reader["col_1"];
        }
    }
}

Mais je reçois le message d'erreur suivant:

Message d'erreur du compilateur: CS0266: Impossible de convertir implicitement le type 'objet' en 'chaîne'. Une conversion explicite existe (il manque un Cast?)
Ligne 90: retourne le lecteur ["col_1"];

Je suis sûr que je commets une erreur très évidente, mais je n'arrive pas à trouver d'exemples à une seule ligne. Tous les exemples que je trouve correspondent à plusieurs lignes renvoyées avec un while loop.

11
oshirowanen

reader["col_1"] renvoie object.

Vous voulez quelque chose comme reader.GetString(reader.GetOrdinal("col_1")).

Éditer -> Je voulais juste ajouter ici une note qui, en plus des préoccupations exprimées par d’autres, un SELECT TOP sans ORDER BY peut vous donner des résultats aléatoires basés sur des modifications de schéma et/ou des analyses de manège.

23
Matt Whitfield

Voici comment je stylerais (et corrigerais) le code:

using (var connection = new SqlConnection(ConfigurationManager.AppSettings["connection"]))
using (var command = new SqlCommand(@"select top 1 col_1, col_2 from table1", connection))
{
    connection.Open();

    using (var reader = command.ExecuteReader())
    {
        if (reader.Read()) // Don't assume we have any rows.
        {
            int ord = reader.GetOrdinal("col_1");
            return reader.GetString(ord); // Handles nulls and empty strings.
        }

        return null;
    }
}

L'utilisation de l'index reader[] vous donnera les types object, ceux-ci doivent être transtypés. Cependant, je touche à peine à ce style et suis toujours favorable à l'utilisation un peu plus verbeuse, mais plus robuste, des ordinaux et à la recherche de types de manière très typée.

Si vous n'avez besoin que de la valeur dans la première colonne de la première ligne, vous pouvez utiliser ExecuteScalar à la place. Cette commande renvoie à nouveau un objet pouvant être transtypé et ne nécessitant pas de lecteur:

using (var connection = new SqlConnection(ConfigurationManager.AppSettings["connection"]))
using (var command = new SqlCommand(@"select top 1 col_1, col_2 from table1", connection))
{
    connection.Open();

    var result = command.ExecuteScalar();
    return result == null ? "" : (string)result;
}
8
Adam Houldsworth

Il me semble que vous ne voulez pas une seule ligne, mais une seule valeur:

SqlConnection sqlConnection = new SqlConnection("Your Connection String");
SqlCommand cmd = new SqlCommand();
Object returnValue;

cmd.CommandText = "SELECT TOP 1 col_name FROM Customers";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;

sqlConnection.Open();

returnValue = cmd.ExecuteScalar();

sqlConnection.Close();

return returnValue.ToString(); //Note you have to cast it to your desired data type
4
yan.kun

Le problème est le type de retour. La méthode que vous utilisez s'attend à ce que vous retourniez une chaîne, mais reader["col_1"] est un objet. Je suggère de retourner reader["col_1"].ToString() ou Convert.ToString(reader["col_1"]).

4
yoozer8

Au lieu de:

 using (reader = command.ExecuteReader())
 {
      reader.Read();
      return reader["col_1"];
 }

Vous devez convertir le reader["col_1"] en chaîne, soit reader["col_1"].ToString() ou reader.GetString(0), comme suit:

return reader.GetString(0);
3
Mahmoud Gamal

Vous pouvez utiliser une instruction if si votre requête ne renvoie qu'une valeur.

[...]
string x = string.Empty;
if(reader.Read()) {
    // make sure the value is not DBNull
    if(DBNull.Value != reader["col_1"]) {
       x = reader.GetString(0);
    }
}
[...]
2
MilkyWayJoe

reader["col_1"] renvoie une object. Je suppose que votre fonction a un type de retour de string, d'où provient l'erreur, elle ne peut pas implicitement convertir la object en une string.

Vous attendez probablement une chaîne renvoyée par col_1, vous pouvez donc la transtyper: (string)reader["col_1"].

2
lc.

le lecteur retourne un objet que vous devriez convertir en ce dont vous avez besoin, dans ce cas une chaîne.

vous pouvez utiliser n'importe lequel de ces codes:

return reader.GetString(0);

return reader["col_1"].ToString();

return Convert.ToString(reader["col_1"]);

return reader["col_1"] as string;

mais n'oubliez pas de fermer la connexion et le lecteur avant de quitter la fonction.

string ret = reader.GetString(0);
reader.Close();
connection.Close();
return ret;
1
Navid Kianfar

Tout d’abord, vous pouvez utiliser le préfixe (string)reader["col_1"]. Vous attendez probablement une chaîne et reader["col_1"] est une object.

1
misha