在c#中查询标量结果

本文关键字:标量 结果 查询 | 更新日期: 2023-09-27 17:54:50

在某些编程环境中,从sql查询中获取标量值很容易:

RowCount = Connection.Execute("SELECT Count(*) FROM TableA").Fields(0).Value

在c#中,给定一个已经打开的SqlConnection变量conn,是否有一种更简单的方法来做同样的事情,而不需要费力地创建SqlCommand, DataReader,并且总共需要大约5行来完成这项工作?

在c#中查询标量结果

SqlCommand有一个ExecuteScalar方法可以做你想做的事情。

 cmd.CommandText = "SELECT COUNT(*) FROM dbo.region";
 Int32 count = (Int32) cmd.ExecuteScalar();

如果您可以使用LINQ2SQL(或EntityFramework),您可以简化实际的查询请求

using (var context = new MyDbContext("connectionString"))
{
    var rowCount = context.TableAs.Count();
}

如果LINQ2SQL是一个选项,与手动创建所有sqlcommand等相比,它还有很多其他好处

ExecuteScalar至少从DataReader中拯救你:

static public int AddProductCategory(string newName, string connString)
{
    Int32 newProdID = 0;
    string sql =
        "INSERT INTO Production.ProductCategory (Name) VALUES (@Name); "
        + "SELECT CAST(scope_identity() AS int)";
    using (SqlConnection conn = new SqlConnection(connString))
    {
        SqlCommand cmd = new SqlCommand(sql, conn);
        cmd.Parameters.Add("@Name", SqlDbType.VarChar);
        cmd.Parameters["@name"].Value = newName;
        try
        {
            conn.Open();
            newProdID = (Int32)cmd.ExecuteScalar();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    return (int)newProdID;
}

(示例取自这篇MSDN文档文章)

您不需要DataReader。以下示例拉回标量值:

Object result;
using (SqlConnection con = new SqlConnection(ConnectionString)) {
       con.Open();
       using (SqlCommand cmd = new SqlCommand(SQLStoredProcName, con)) {
       result = cmd.ExecuteScalar();
      }
}

调查命令。ExecuteScalar:

using(var connection = new SqlConnection(myConnectionString))
{
    connection.Open();
    using(var command = connection.CreateCommand())
    {
        command.CommandType = CommandType.Text;
        command.CommandText = mySql;
        var result = (int)command.ExecuteScalar();
    }
}

如果你真的觉得很懒,就像我们一样把它封装在一个扩展方法中。

编辑:根据要求,一个扩展方法:

public static T ExecuteScalar<T> (this SqlConnection connection, string sql)
{
    if (connection == null)
    {
        throw new ArgumentNullException("connection");
    }
    if (string.IsNullOrEmpty(sql))
    {
        throw new ArgumentNullException("sql");
    }
    using(var command = connection.CreateCommand())
    {
        command.CommandText = sql;
        command.CommandType = CommandType.Text;
        return (T)command.ExecuteScalar();
    }
}

注意,这个版本假定您事先已经正确地构建了SQL。我可能会为这个扩展方法创建一个单独的重载,它接受两个参数:存储过程名称和List。这样,您就可以保护自己免受不必要的SQL注入攻击。