简体   繁体   English

SQL 查询到 C# 中的标量结果

[英]SQL query to scalar result in C#

In some programming contexts getting a scalar value from a sql query is easy:在某些编程上下文中,从 sql 查询中获取标量值很容易:

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

In C#, given a SqlConnection variable conn that is already open, is there a simpler way to do this same thing without laboriously creating a SqlCommand, a DataReader, and all in all taking about 5 lines to do the job?在 C# 中,给定一个已经打开的 SqlConnection 变量conn ,是否有更简单的方法来做同样的事情,而无需费力地创建 SqlCommand、DataReader 并且总共需要大约 5 行来完成这项工作?

SqlCommand has an ExecuteScalar method that does what you want. SqlCommand 有一个 ExecuteScalar 方法可以做你想做的事。

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

If you can use LINQ2SQL (or EntityFramework) you can simplify the actual query asking to如果您可以使用 LINQ2SQL(或 EntityFramework),您可以简化实际查询要求

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

If LINQ2SQL is an option that has lots of other benefits too compared to manually creating all SqlCommands, etc.如果 LINQ2SQL 是一个选项,与手动创建所有 SqlCommand 等相比,它还有很多其他好处。

There is ExecuteScalar which saves you at least from the DataReader :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;
}

(Example taken from this MSDN documentation article ) (示例取自此 MSDN 文档文章

Investigate Command.ExecuteScalar:调查 Command.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();
    }
}

If you're feeling really lazy, encapsulate it all in an extension method, like we do.如果您真的很懒惰,请像我们一样将其全部封装在扩展方法中。

EDIT: As requested, an extension method:编辑:根据要求,扩展方法:

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();
    }
}

Note, this version assumes you've properly built the SQL beforehand.请注意,此版本假定您事先已正确构建 SQL。 I'd probably create a separate overload of this extension method that took two parameters: the stored procedure name and a List.我可能会为这个扩展方法创建一个单独的重载,它采用两个参数:存储过程名称和一个列表。 That way, you could protect yourself against unwanted SQL injection attacks.这样,您可以保护自己免受不必要的 SQL 注入攻击。

You do not need a DataReader.您不需要 DataReader。 This example pulls back the scalar value:此示例拉回标量值:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM