c#你如何从sqldatareader返回数据集?

Posted

技术标签:

【中文标题】c#你如何从sqldatareader返回数据集?【英文标题】:c# how do you return dataset from sqldatareader? 【发布时间】:2010-11-04 17:55:19 【问题描述】:

我在公共课上有这个:

SqlConnection myConnection = new SqlConnection("Data Source=hermes;database=qcvalues; Integrated Security=SSPI;");
myConnection.Open();
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand(InitializeQuery(), myConnection);
myReader = myCommand.ExecuteReader();

我需要一个控件的数据源来从 myReader 获取数据集。

不幸的是,这很难做到,因为控件位于表单(一个单独的类)上。如何将myReader 数据集返回到表单上控件的datasource 属性中?

【问题讨论】:

如果只返回一个结果集,请使用 DataTable。如果有多个,请使用 DataSet。 根据评论者here,如果你想阅读它,他会显示 DataAdapter.Fill 的代码,Fill 方法有它自己的 try-finally,它会关闭连接,所以你不会不得不。另见this SO question。只要你代码中没有打开连接,Fill会在出现异常时关闭连接。 【参考方案1】:

你没有。改用 DataAdapter:

var ds = new DataSet();

using(var conn = new SqlConnection(connString))

    conn.Open();
    var command = new SqlCommand(InitializeQuery(), conn);
    var adapter = new SqlDataAdapter(command);

    adapter.Fill(ds);

【讨论】:

@我是一个女孩 - 它会工作。另一方面,这就是 DataAdapter 的用途(获取数据的内存表示并将其放入容器中)。 我相信DataAdapter会做连接的打开和关闭。是否也需要将其包装在 using 语句中? @DOK - 是的。即使适配器包装了打开/关闭调用,当你完成它时仍然没有任何东西可以处理(例如,在发生异常的情况下)。 @JustinNiessner Sanjib Bose 的回答有什么问题?似乎我们可以通过这种方式从 DataReader 加载数据集。我不想使用 DataAdapter 的原因是 - 它没有异步实现。【参考方案2】:

如果您可以使用 DataAdapter 子类或使用以下内容:

DataTable myTable = new DataTable();

myTable.Load(myCommand.ExecuteReader());

然后将DataTable返回给客户端。

【讨论】:

如果您只需要一个 DataTable 而不是整个 DataSet,这是一个好主意。 如果一个简单的查询返回一组行,一般不需要返回所有DataSet :) 我想利用 Command.ExecuteReaderAsync() 进行异步/等待,但仍返回一个 DataTable。这看起来是实现这一目标的最佳方式。谢谢。【参考方案3】:
IDataReader reader;
DataSet ds;

while (!reader.IsClosed)
   ds.Tables.Add().Load(reader);

【讨论】:

我不明白为什么这个答案被否定了。它确实回答了“从 myReader 获取数据集”的问题。就这么简单。 对于没有数据适配器的 Microsoft.Data.Sqlite 的优秀答案。【参考方案4】:

您可以更改代码以使其返回 DataSet,而不是返回 SqlDataReader。

SqlConnection myConnection = new SqlConnection("Data Source=hermes;database=qcvalues; Integrated Security=SSPI;");
DataSet dst = new DataSet();
SqlDataAdapter dap = new SqlDataAdapter(InitializeQuery(), mConnection);
dap.Fill(dst, "DataSetName");

这种方法的一个巧妙之处在于 Fill 会为您打开和关闭数据库连接。

【讨论】:

不一定是 DataSet - 如果合适,您可以填写一个更轻量级的 DataTable。 @DOK 数据集名称应该是什么? @i am a girl - 您只需将 DataTable 传递给 .Fill 方法,而不是 DataSet。见:msdn.microsoft.com/en-us/library/… 如果你有多个DataTables,它只需要是一个DataSet,特别是如果你有这些表之间的关系(例如主键-外键)。这在桌面应用程序中可能更为常见,其中数据在客户端上保留了一段时间。如果您只有一个 DataTable,则不需要 DataSet。 DataSet 名称可以是任何东西,也可以什么都不是。如果你有多个,给它一个名字会很有帮助。同样的事情也适用于数据表。因此,这些名称是可选的。【参考方案5】:

如果你的SelectCommand是存储过程,适配器的Fill方法会引发异常。

在这些情况下,您可以使用:

DataTable dt = new DataTable();
dt = sdr.GetSchemaTable();
dt.Constraints.Clear();
dt.BeginLoadData();
dt.Load(sdr);
//dt.EndLoadData(); // Enables constraints again

【讨论】:

【参考方案6】:

下面的 sn-p 在SqlServer 上对我来说很好:

public DataSet executeProcedure(String procudureName, params SqlParameter[] sqlParameters)

    return executeSqlCommand(procudureName, CommandType.StoredProcedure, sqlParameters);

public DataSet executeSql(String commandText, params SqlParameter[] sqlParameters)

    return executeSqlCommand(commandText, CommandType.Text, sqlParameters);

public DataSet executeSqlCommand(String commandText, CommandType Commandtype, params SqlParameter[] sqlParameters)

    DataSet myset = new DataSet();
    using (var command = Database.GetDbConnection().CreateCommand())
    
        command.CommandText = commandText;
        command.CommandType = Commandtype;
        foreach (var _kv in sqlParameters)
        
            DbParameter _dbpara = command.CreateParameter();
            _dbpara.ParameterName = _kv.ParameterName;
            _dbpara.Value = _kv.Value;
            command.Parameters.Add(_dbpara);
        
        Database.OpenConnection();
        DbDataAdapter adapter = DbProviderFactories.GetFactory(Database.GetDbConnection()).CreateDataAdapter();
        adapter.SelectCommand = command;
        adapter.Fill(myset);
    
    return myset;

DbDataAdapter 实例可以从 DbProviderFactories 类中检索到。

DbDataAdapter adapter = DbProviderFactories.GetFactory(Database.GetDbConnection()).CreateDataAdapter();

【讨论】:

以上是关于c#你如何从sqldatareader返回数据集?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SqlDataReader 读取多个结果集? [复制]

如何从 SqlDataReader 获取列的表名

如何在 JavaScript 中使用 C# SQLDataReader 对象

在 C# 中将 SQL Datareader 转换为数据集

如何在 C# 中使用 SqlDataReader 获取行数

C#利用SqlDataReader读取SQL Server数据表