如何在C#中执行通用SQL命令?

时间:2018-07-24 12:52:28

标签: c# sql-server

我正在尝试编写一个方法,该方法仅接受一个SQL命令的字符串,并针对预定义的数据库/服务器运行它……这是我到目前为止所拥有的:

public class TSqlConnector : IDbConnector
{
    private readonly string _connectionString;

    public TSqlConnector(string conn)
    {
        _connectionString = conn;
    }
    public IEnumerable<object[]> ExecuteCommand(string query)
    {
        var res = new List<object[]>();
        try
        {
            using (SqlConnection sql = new SqlConnection(_connectionString))
            {
                sql.Open();
                SqlCommand cmd = new SqlCommand(query, sql);
                var reader = cmd.ExecuteReader();
                DataTable tbl = new DataTable();
                while (reader.Read())
                {
                    var dr = tbl.NewRow();
                    dr.ItemArray = new object[reader.FieldCount];
                    reader.GetValues(dr.ItemArray);
                    res.Add(dr.ItemArray);
                }

            }

            return res;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
            throw;
        }
    }
} 

但是,这段代码给我一个错误,指出

  

输入数组长于此表中的列数。

我搜索了错误消息,显然我首先必须使用tbl.Add("ColumnName", typeof(type));

定义DataTable的列。

但是,这完全破坏了我试图做的事情-编写通用版本。我所需要的只是某种结构,其中包含如果我在SSMS中键入相同的命令,我将从SqlServer中获得的信息,我并不在乎读取C#中的数据必须经过哪些步骤。每行使用一个对象数组,必须将每个对象手动转换为字符串,int或完全可接受的字符串,即使是类似CSV的字符串也很好

我唯一不想做的就是添加表的定义或固定数量的行。每个使用ExecuteCommand()的方法都必须知道返回什么类型的对象数组,这很好,但是除了SQL命令之外,添加一些包含类型和列名的复杂数据结构似乎有些过分。

有没有更简单的方法来实现这一目标?

2 个答案:

答案 0 :(得分:1)

您拥有的是IDataReader中的cmd.ExecuteReader();

要将结果加载到DataTable中,可以使用Load方法,如下所示:

var reader = cmd.ExecuteReader();
DataTable tbl = new DataTable();
tbl.Load(reader);
// now tbl contains the corresponding columns and rows from your sql command.

// Then you can return the ItemArrays from each row;

return tbl.Rows.Cast<DataRow>().Select(row => row.ItemArray);

答案 1 :(得分:0)

我使用了这样的代码来输入通用的SQL查询并以数据表的形式返回结果。当然,您必须根据需要解析结果。

private DataTable QueryToTable(string sql, string cs)
{

    var ds = new DataSet();

    using (var adapter = new SqlDataAdapter(sql, cs))
    {
        adapter.Fill(ds);
    }

    return ds.Tables(0);
}