SqlDataAdapter::Fill 是获取整个结果集还是按需获取?
Does SqlDataAdapter::Fill fetch the whole result set or is it on-demand?
我试图将 DataGridView 连接到 SQL 服务器, 中概述的解决方案使用了 SqlDataAdapter 和 DataTable:
var adapter = new SqlDataAdapter("select * from foo", "server=myhost-pc\sqlexpress;trusted_connection=yes;database=test1");
var table = new DataTable();
adapter.Fill(table);
view.DataSource = table;
我想知道这个方法是否从服务器获取整个数据集,或者它是否将 DataGridView 连接到服务器以便它可以按需获取新行。
例如,如果 table 有 100 万行,是否会在 SqlDataAdapter::Fill 返回之前将所有行提取并写入 DataTable
对象?
是的,它将创建对象并在您的网格视图上实现以显示您的所有数据,问题是您如何编写 SQL 查询,您可以使用一些 SQL 关键字,如 TOP、LIMIT、OFFSET。
限制通过 SQL 加载的行数,要么在质量上(WHERE...)限制它们,要么通过一个相当生硬的 LIMIT 子句限制它们。您还可以使用 DataAdapter
加载 "pages" 或组中的行 - 一次一点。这使用 MySQL 但它适用于 DBProviders 的许多其他(全部?):
int pageSize = 10000;
int page = 0;
...
初始加载:
string SQL = "SELECT * FROM Sample";
using (MySqlConnection dbCon = new MySqlConnection(MySQLConnStr))
{
dtSample = new DataTable();
daSample = new MySqlDataAdapter(SQL, dbCon);
daSample.FillSchema(dtSample, SchemaType.Source);
dbCon.Open();
int Rows = daSample.Fill((page*pageSize), pageSize, dtSample);
}
dgv2.DataSource = dtSample;
this.lblPages.Text = String.Format("Rows {0} - {1}",
((page * pageSize) + 1),
(page + 1 * pageSize));
page += 1;
关键是 DataAdapter(int, int, DataTable)
重载:它允许您指定要加载的第一行和行数。我不会为每个页面重新创建 DataAdapter
,而是使用 form/class 一级。阅读下一页会给您一些选择:
dgv2.SuspendLayout();
dtSample.Rows.Clear();
int Rows = daSample.Fill((page * pageSize), pageSize, dtSample);
dgv2.ResumeLayout();
this.lblPages.Text = String.Format("Rows {0} - {1}",
((page * pageSize) + 1),
(page + 1 * pageSize));
if (Rows != pageSize) // last page?
page = 0;
else
page += 1;
如果您不清除行,DataTable
会累积它们:也就是说,在加载第二组后,它将具有页面的所有行1 和 2。
让它们累积起来很有用,这样任何给定的集合都只加载一次。如果一次只显示一页仍然很重要,您可以使用 DataView
仅显示当前组:
我试图将 DataGridView 连接到 SQL 服务器, 中概述的解决方案使用了 SqlDataAdapter 和 DataTable:
var adapter = new SqlDataAdapter("select * from foo", "server=myhost-pc\sqlexpress;trusted_connection=yes;database=test1");
var table = new DataTable();
adapter.Fill(table);
view.DataSource = table;
我想知道这个方法是否从服务器获取整个数据集,或者它是否将 DataGridView 连接到服务器以便它可以按需获取新行。
例如,如果 table 有 100 万行,是否会在 SqlDataAdapter::Fill 返回之前将所有行提取并写入 DataTable
对象?
是的,它将创建对象并在您的网格视图上实现以显示您的所有数据,问题是您如何编写 SQL 查询,您可以使用一些 SQL 关键字,如 TOP、LIMIT、OFFSET。
限制通过 SQL 加载的行数,要么在质量上(WHERE...)限制它们,要么通过一个相当生硬的 LIMIT 子句限制它们。您还可以使用 DataAdapter
加载 "pages" 或组中的行 - 一次一点。这使用 MySQL 但它适用于 DBProviders 的许多其他(全部?):
int pageSize = 10000;
int page = 0;
...
初始加载:
string SQL = "SELECT * FROM Sample";
using (MySqlConnection dbCon = new MySqlConnection(MySQLConnStr))
{
dtSample = new DataTable();
daSample = new MySqlDataAdapter(SQL, dbCon);
daSample.FillSchema(dtSample, SchemaType.Source);
dbCon.Open();
int Rows = daSample.Fill((page*pageSize), pageSize, dtSample);
}
dgv2.DataSource = dtSample;
this.lblPages.Text = String.Format("Rows {0} - {1}",
((page * pageSize) + 1),
(page + 1 * pageSize));
page += 1;
关键是 DataAdapter(int, int, DataTable)
重载:它允许您指定要加载的第一行和行数。我不会为每个页面重新创建 DataAdapter
,而是使用 form/class 一级。阅读下一页会给您一些选择:
dgv2.SuspendLayout();
dtSample.Rows.Clear();
int Rows = daSample.Fill((page * pageSize), pageSize, dtSample);
dgv2.ResumeLayout();
this.lblPages.Text = String.Format("Rows {0} - {1}",
((page * pageSize) + 1),
(page + 1 * pageSize));
if (Rows != pageSize) // last page?
page = 0;
else
page += 1;
如果您不清除行,DataTable
会累积它们:也就是说,在加载第二组后,它将具有页面的所有行1 和 2。
让它们累积起来很有用,这样任何给定的集合都只加载一次。如果一次只显示一页仍然很重要,您可以使用 DataView
仅显示当前组: