返回单行

16

我想从数据库中返回一行记录:

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"];
        }
    }
}

但我遇到了以下错误信息:

编译器错误消息:CS0266:无法隐式将类型“object”转换为“string”。 存在显式转换(您是否缺少转换?)
第90行:return reader["col_1"];

我确定我犯了一个非常明显的错误,但我似乎找不到任何单行示例,所有示例都是使用while循环返回多个行。


6
顺便提一下,你返回的是单元格而不是整行!如果这就是你想要的,那就看看 command.ExecuteScalar() - banging
1
@banging,听起来很准确。但是使用ExecuteScalar是否可能返回单个字符串而不是整数? - oshirowanen
2
ExecuteScalar() 返回一个对象,因此您需要进行适当的转换,例如 (string)command.ExecuteScalar() - banging
10个回答

27

reader["col_1"] 返回 object

您需要类似于reader.GetString(reader.GetOrdinal("col_1"))的东西。

编辑 - 我只想在这里添加一个注释,除了其他人提出的问题之外,没有ORDER BYSELECT TOP可能会因模式更改和/或旋转扫描而给您带来随机结果。


13
这是我会如何设计(和修复)代码的方式:
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;
    }
}

使用索引reader[]将给您object类型,这些需要转换。但是,我很少使用那种风格,总是更喜欢略微冗长但更健壮的方式,按序数请求类型并以强类型方式进行请求。
如果您只需要第一行第一列中的值,则可以使用ExecuteScalar,同样返回一个可以转换且不需要读取器的对象:
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;
}

5

问题在于返回类型。您所在的方法期望您返回一个字符串,但 reader["col_1"] 是一个对象。我建议返回 reader["col_1"].ToString()Convert.ToString(reader["col_1"])


3
我不同意称呼ToString方法,因为即使基础类型更改,它也会继续工作。在我看来,如果类型更改,我希望得到一个错误提示。如果确定值是字符串类型,可以将其强制转换为(string)reader[""],或者更好的做法是使用reader.GetString(0)来获取值。 - Adam Houldsworth
2
这个不支持 null 值。请使用 Convert.ToString(reader["col_1"]) 代替。 - banging

5
对我来说,你似乎不需要一行,只需要一个单独的值:
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

改为:

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

您需要将 reader["col_1"] 转换为字符串,可以使用 reader["col_1"].ToString() 或者 reader.GetString(0) 方法,例如:

return reader.GetString(0);

1
这将返回col_2的值,而不是col_1 - Guffa
1
实际上,col_1 是第一列 - 但是列索引是从零开始的,所以您应该使用 reader.GetString(0)col_1 作为字符串获取... - marc_s

3

reader["col_1"] 返回一个 object。我猜你的函数应该返回一个 string 类型,这就是错误的来源,因为不能隐式地将 object 转换成 string

你可能期望从 col_1 返回一个字符串,那么你可以直接进行强制类型转换:(string)reader["col_1"]


3
您可以使用一个if语句,如果您的查询只返回一个值。
[...]
string x = string.Empty;
if(reader.Read()) {
    // make sure the value is not DBNull
    if(DBNull.Value != reader["col_1"]) {
       x = reader.GetString(0);
    }
}
[...]

1
我不同意称呼 ToString,因为即使数据库类型更改,它仍将继续工作。在我看来,如果它从 string 更改,我希望得到一个告诉我这一点的错误。如果确实是字符串,请将其转换为 (string)reader[""] 或者更好的方法是请求 reader.GetString(0) - Adam Houldsworth
请注意,我之前写过 var x = ...,所以现在用 ToString() 指定类型,但是 reader.GetString(0) 更好。 - MilkyWayJoe
不,我并不是在说代码中的类型是错误的,我是在说它会隐藏一个问题,即数据库中的值不再是字符串,因为“.ToString”将成功地将除“null”以外的任何内容转换为字符串。 - Adam Houldsworth
我明白了,但既然你提到了,我已经添加了一个对 DBNull 的检查,并且我赞成使用内置函数。这就是为什么我做出了更改。 - MilkyWayJoe

2
今日免费次数已满, 请开通会员/明日再来

2
读取器返回对象,你需要将其转换为你所需的类型,本例中是字符串。
可以使用以下任何代码: return reader.GetString(0); return reader["col_1"].ToString(); return Convert.ToString(reader["col_1"]); return reader["col_1"] as string; 但在离开函数之前不要忘记关闭连接和读取器。
string ret = reader.GetString(0);
reader.Close();
connection.Close();
return ret;

1
他在 using 中已经包含了所有内容,因此不需要显式地关闭任何东西! - banging

2

按照以下步骤选择单列,并显示它们。

    //create a connection
    SqlConnection sqlConnection = new SqlConnection("Your Connection String");
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = sqlConnection;

    //open the connection
    sqlConnection.Open();

    //Your command query string
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = "SELECT TOP 1 col_name FROM Customers";


    //Execute the reader
    SqlDataReader result  = cmd.ExecuteReader();
    result.Read();

    //close the connection
    sqlConnection.Close();

    return result["coiumn_name"].ToString(); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接