如何用多个表填充数据集?
Posted
技术标签:
【中文标题】如何用多个表填充数据集?【英文标题】:How to fill Dataset with multiple tables? 【发布时间】:2012-07-05 22:36:29 【问题描述】:我正在尝试填充包含 2 个具有一对多关系的表的 DataSet。 我正在使用 DataReader 来实现这一点:
public DataSet SelectOne(int id)
DataSet result = new DataSet();
using (DbCommand command = Connection.CreateCommand())
command.CommandText = "select * from table1";
var param = ParametersBuilder.CreateByKey(command, "ID", id, null);
command.Parameters.Add(param);
Connection.Open();
using (DbDataReader reader = command.ExecuteReader())
result.MainTable.Load(reader);
Connection.Close();
return result;
但是我只有一张桌子坐满了。如何实现我的目标 - 填写两个表格?
如果可能的话,我想使用 DataReader 而不是 DataAdapter。
【问题讨论】:
为什么你会期望两个表都被填满?您的命令仅包含一个返回单个表的select
语句。
为什么不使用SqlDataAdapter
及其Fill(...)
方法而不是DbCommand
?
@Nikola Anusev - 我知道,所以我只是提出任何建议
@jonnyGold - 预演。 DataReader 快,DataAdapter 慢。这对我来说至关重要
@AndriyZakharko:DataAdapter 在后台也使用了 DataReader。 ***.com/a/334667/284240 reader 的唯一优势是您可以一次将一条记录流式传输,而不是将所有记录加载到内存中。
【参考方案1】:
如果您发出带有多个选择语句的单个命令,您可以使用 NextResult 方法移动到数据读取器中的下一个结果集:http://msdn.microsoft.com/en-us/library/system.data.idatareader.nextresult.aspx
我展示了它的外观:
public DataSet SelectOne(int id)
DataSet result = new DataSet();
using (DbCommand command = Connection.CreateCommand())
command.CommandText = @"
select * from table1
select * from table2
";
var param = ParametersBuilder.CreateByKey(command, "ID", id, null);
command.Parameters.Add(param);
Connection.Open();
using (DbDataReader reader = command.ExecuteReader())
result.MainTable.Load(reader);
reader.NextResult();
result.SecondTable.Load(reader);
// ...
Connection.Close();
return result;
【讨论】:
你可以做result.Load(reader)
。 Load
方法将处理多个结果集。
@AMissico,是的,但是不能用 DataSet.Load 明确说明要填充哪个结果集的表,如果您以其他顺序定义表,它将中断。您还必须说明其他参数。
你今天让我笑了。【参考方案2】:
Here is very good answer of your question
请参阅上面 MSDN 页面上提到的示例:-
【讨论】:
【参考方案3】:可以通过向数据库发送多个请求来填充具有多个表的 DataSet,或者以更快的方式:可以在单个请求中将多个 SELECT 语句发送到数据库服务器。这里的问题是从查询生成的表具有自动名称 Table 和 Table1。但是,生成的表名可以映射到应在 DataSet 中使用的名称。
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT * FROM Customers; SELECT * FROM Orders", connection);
adapter.TableMappings.Add("Table", "Customer");
adapter.TableMappings.Add("Table1", "Order");
adapter.Fill(ds);
【讨论】:
感谢您的回复,但根据我的任务 - 我需要使用 DataReader 而不是 DataAdapter :在我的问题中有所描述 用 TableMappings.Add 添加不是必要的 @Iman - 如果您按照示例将 SQL 发送到服务器,则可能没有必要,但如果您正在调用存储过程并返回多个 SELECT,则可能没有必要。这个答案对我很有用【参考方案4】:这是一个老话题,但对某些人来说可能有用:
DataSet someDataSet = new DataSet();
SqlDataAdapter adapt = new SqlDataAdapter();
using(SqlConnection connection = new SqlConnection(ConnString))
connection.Open();
SqlCommand comm1 = new SqlCommand("SELECT * FROM whateverTable", connection);
SqlCommand comm2g = new SqlCommand("SELECT * FROM whateverTable WHERE condition = @0", connection);
commProcessing.Parameters.AddWithValue("@0", "value");
someDataSet.Tables.Add("Table1");
someDataSet.Tables.Add("Table2");
adapt.SelectCommand = comm1;
adapt.Fill(someDataSet.Tables["Table1"]);
adapt.SelectCommand = comm2;
adapt.Fill(someDataSet.Tables["Table2"]);
【讨论】:
如果 sql(store proc) 返回多个表,该如何处理? 你可以使用adapt.Fill(someDataSet)
,而不是adapt.Fill(someDataSet.Tables["Table1"])
。因为当然你的存储过程会重新运行表,但前提是它真的返回 TABLES 而不是来自多个表的一组 COLUMNS。
感谢您的回复,会试试这个东西:-)【参考方案5】:
protected void Page_Load(object sender, EventArgs e)
SqlConnection con = new SqlConnection("data source=.;uid=sa;pwd=123;database=shop");
//SqlCommand cmd = new SqlCommand("select * from tblemployees", con);
//SqlCommand cmd1 = new SqlCommand("select * from tblproducts", con);
//SqlDataAdapter da = new SqlDataAdapter();
//DataSet ds = new DataSet();
//ds.Tables.Add("emp");
//ds.Tables.Add("products");
//da.SelectCommand = cmd;
//da.Fill(ds.Tables["emp"]);
//da.SelectCommand = cmd1;
//da.Fill(ds.Tables["products"]);
SqlDataAdapter da = new SqlDataAdapter("select * from tblemployees", con);
DataSet ds = new DataSet();
da.Fill(ds, "em");
da = new SqlDataAdapter("select * from tblproducts", con);
da.Fill(ds, "prod");
GridView1.DataSource = ds.Tables["em"];
GridView1.DataBind();
GridView2.DataSource = ds.Tables["prod"];
GridView2.DataBind();
【讨论】:
请添加一些解释。【参考方案6】: string connetionString = null;
SqlConnection connection ;
SqlCommand command ;
SqlDataAdapter adapter = new SqlDataAdapter();
DataSet ds = new DataSet();
int i = 0;
string firstSql = null;
string secondSql = null;
connetionString = "Data Source=ServerName;Initial Catalog=DatabaseName;User ID=UserName;Password=Password";
firstSql = "Your First SQL Statement Here";
secondSql = "Your Second SQL Statement Here";
connection = new SqlConnection(connetionString);
try
connection.Open();
command = new SqlCommand(firstSql, connection);
adapter.SelectCommand = command;
adapter.Fill(ds, "First Table");
adapter.SelectCommand.CommandText = secondSql;
adapter.Fill(ds, "Second Table");
adapter.Dispose();
command.Dispose();
connection.Close();
//retrieve first table data
for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
MessageBox.Show(ds.Tables[0].Rows[i].ItemArray[0] + " -- " + ds.Tables[0].Rows[i].ItemArray[1]);
//retrieve second table data
for (i = 0; i <= ds.Tables[1].Rows.Count - 1; i++)
MessageBox.Show(ds.Tables[1].Rows[i].ItemArray[0] + " -- " + ds.Tables[1].Rows[i].ItemArray[1]);
catch (Exception ex)
MessageBox.Show("Can not open connection ! ");
【讨论】:
【参考方案7】:public DataSet GetDataSet()
try
DataSet dsReturn = new DataSet();
using (SqlConnection myConnection = new SqlConnection(Core.con))
string query = "select * from table1; select* from table2";
SqlCommand cmd = new SqlCommand(query, myConnection);
myConnection.Open();
SqlDataReader reader = cmd.ExecuteReader();
dsReturn.Load(reader, LoadOption.PreserveChanges, new string[] "tableOne", "tableTwo" );
return dsReturn;
catch (Exception)
throw;
【讨论】:
【参考方案8】:DataTable
的方法Load
在DataReader
上执行NextResult
,因此在使用Load
时不应显式调用NextResult
,否则将省略序列中的奇数表。
这是使用DataReader
加载多个表的通用解决方案。
// your command initialization code here
// ...
DataSet ds = new DataSet();
DataTable t;
using (DbDataReader reader = command.ExecuteReader())
while (!reader.IsClosed)
t = new DataTable();
t.Load(rs);
ds.Tables.Add(t);
【讨论】:
这个对我有用,当我不确定在存储过程中返回了多少个单独的表时非常有用(正如我刚刚在使用加密存储过程访问遗留数据库时发现的那样)跨度> 【参考方案9】:DataSet ds = new DataSet();
using (var reader = cmd.ExecuteReader())
while (!reader.IsClosed)
ds.Tables.Add().Load(reader);
return ds;
【讨论】:
请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。以上是关于如何用多个表填充数据集?的主要内容,如果未能解决你的问题,请参考以下文章