Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中标量结果的SQL查询#_C#_Sql - Fatal编程技术网

C# C语言中标量结果的SQL查询#

C# C语言中标量结果的SQL查询#,c#,sql,C#,Sql,在某些编程环境中,从sql查询中获取标量值很容易: RowCount = Connection.Execute("SELECT Count(*) FROM TableA").Fields(0).Value 在C#中,给定一个已经打开的SqlConnection变量conn,有没有一种更简单的方法来完成同样的事情,而不必费力地创建SqlCommand、DataReader,总的来说需要大约5行代码来完成这项工作?SqlCommand有一个ExecuteScalar方法,可以实现您想要的功能 c

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

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

在C#中,给定一个已经打开的SqlConnection变量
conn
,有没有一种更简单的方法来完成同样的事情,而不必费力地创建SqlCommand、DataReader,总的来说需要大约5行代码来完成这项工作?

SqlCommand有一个ExecuteScalar方法,可以实现您想要的功能

 cmd.CommandText = "SELECT COUNT(*) FROM dbo.region";
 Int32 count = (Int32) cmd.ExecuteScalar();
至少从
数据读取器
中可以保存以下内容:

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;
}
(示例取自)

如果可以使用LINQ2SQL(或EntityFramework),则可以简化请求

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

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

调查命令.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();
    }
}
publicstatict ExecuteScalar(此SqlConnection连接,字符串sql)
{
if(连接==null)
{
抛出新的ArgumentNullException(“连接”);
}
if(string.IsNullOrEmpty(sql))
{
抛出新的ArgumentNullException(“sql”);
}
使用(var command=connection.CreateCommand())
{
command.CommandText=sql;
command.CommandType=CommandType.Text;
return(T)command.ExecuteScalar();
}
}

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

您不需要DataReader。此示例返回标量值:

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

谢谢命令对象是否需要使用
Dispose
或使用
块在
内部进行特殊处理?是的,我相信是这样。SqlCommand从DbCommand获得IDisposable。我之所以授予您答案奖励,是因为您首先给出了
ExecuteScalar
,不过如果使用
info包含
,则会更好。ExecuteOnQuery返回受影响的行数。ExecuteScaler最好在您希望返回集正好是一列和一行值时使用。例如标识值或计数。您不需要将其转储到数据集中,然后尝试读取表[0]行[0]列[0]您有可以共享的扩展方法的示例吗?您参加聚会只晚了几秒钟,所以我会给您打分。为什么在
Int32
int
之间切换?他们不一样吗?为什么不用一个呢?谢谢,埃里克。这是MSDN中的一个示例。Int32和int是一样的。