【问题标题】:Trying to load a DataSet, but it is always null. Regular sqlReader.GetValue() is not尝试加载数据集,但它始终为空。常规 sqlReader.GetValue() 不是
【发布时间】:2011-09-27 22:20:58
【问题描述】:

我不怎么使用数据集。通常发现自己使用 ORM 或只是一个基本的 sqlReader.Read(),然后是一些 GetValues()。我正在处理一些遗留代码,这些代码到处都有数据集,并且在修复错误时试图干燥其中的一些。

但是,我似乎无法真正将数据加载到非类型化 DataSet 中。

public static DataSet ExecuteStoredProcedure(string storedProcedure, DBEnum db, IEnumerable<SqlParameter> parameters)
{
    DataSet result = new DataSet();
    using (SqlConnection connection = SqlHelper.GetSqlConnection(db))
    {
        SqlCommand command = connection.CreateCommand();
        command.CommandType = CommandType.StoredProcedure;
        command.CommandText = storedProcedure;

        if (parameters != null)
            foreach (SqlParameter parameter in parameters)
                command.Parameters.Add(parameter);

        connection.Open();
        DataTable table = new DataTable();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            table.Load(reader);
        }
        result = table.DataSet; // table.DataSet is always empty!
   }
   return result;
}

我假设 table.Load(reader) 执行了所有必要的 reader.Read() 调用......但我继续尝试在 table.Load() 之前使用和不使用 reader.Read() 都没有有用。

我知道被调用的存储过程实际上是在返回数据。如果我做这样的事情,我可以看到数据就好了:

using(SqlDataReader reader = command.ExecuteReader())
{
    reader.Read();
    object test = reader.GetValue(0); // returns the expected value
}

似乎我在这里遗漏了一些简单的东西,但我一直在为这个问题摸不着头脑。

这是在 .NET 3.5 中。

【问题讨论】:

    标签: c# .net-3.5 dataset


    【解决方案1】:

    如果可以的话,我建议使用SqlDataAdapter 来填充DataTable

    using(SqlDataAdapter sqlDA = new SqlDataAdapter(command))
    {
        sqlDA.Fill(table);
    }
    

    【讨论】:

    • 我没有看到你在回答中使用了 DataTable,所以当我尝试它时,我只是在它的位置使用了 DataSet,这似乎工作正常。
    • @Matt - 是的,您可以将DataSetDataTable 传递给Fill()。忘了提那个。很高兴我能帮上忙。
    【解决方案2】:

    您的逻辑显示 DataTable 正在加载来自阅读器的数据,但 DataTable 从未添加到数据集中。

    【讨论】:

    • 但是 DataTable.DataSet 是空的 .... DataTable::Load() 之后的其他地方的数据吗?
    • 您仍然可以访问 DataTable 中的数据,将 DataSet 视为 DataTables 的容器。
    • 如果存储过程包含多个表结果怎么办?
    • 多个表结果不适合单个数据表...去看看msdn.microsoft.com/en-us/library/879f39d8.aspx,它可以很好地为您解决所有这些问题。 :)
    【解决方案3】:

    我认为应该首先创建数据集。事实上,您可以使用 DataSet.Load 代替 DataTable.Load。 DataSet.Load 应该创建数据表,但反过来就不行了。

    【讨论】:

      【解决方案4】:

      DataSet 包含 DataTables 而不是相反。因此,如果您想创建一个要返回的 DataSet,那么您可能需要创建一个新数据集,然后在返回之前将您的 DataTable 添加到其中。如果 DataTable 不在 DataSet 中,则对其父数据集的引用将始终为空。

      话虽如此,我也推荐 Jason Evans 关于使用 SqlDataAdapter 的建议。

      【讨论】:

        【解决方案5】:

        将数据集视为表的集合,以及有关它们之间关系的可选信息。

        在您的示例代码中,您正在创建一个不属于 DataSet 的独立表。要实用地创建作为数据集一​​部分的表,您可以执行以下操作:

        DataSet ds = new DataSet();
        DataTable dt = ds.Tables.Add();
        //or
        ds.Tables.Add(MyAlreadyCreatedTable);
        

        上面的 Jason Evans 也是正确的,正如他所演示的那样,使用 SqlDataAdaptors 填充 DataTables 和 DataSets 要简单得多。

        最后,您编写的方法旨在返回一个数据集。但它只从它正在调用的存储过程中捕获一个结果集。一个过程可能会返回任意数量的单独结果。

        您需要做的就是更改以下内容:

            DataTable table = new DataTable();
            using (SqlDataReader reader = command.ExecuteReader())
            {
                table.Load(reader);
            }
        

        //you can skip creating a new DataTable object
        using (SqlDataAdapter da = new SqlDataAdapter(command))
        {
            da.Fill(result); // the result set you created at the top
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-19
          • 2019-02-27
          • 2017-06-18
          • 2014-03-28
          • 2021-02-24
          相关资源
          最近更新 更多