【问题标题】:Does SqlDataAdapter::Fill fetch the whole result set or is it on-demand?SqlDataAdapter::Fill 是获取整个结果集还是按需获取?
【发布时间】:2016-08-08 12:13:03
【问题描述】:

我试图将 DataGridView 连接到 SQL Server,https://stackoverflow.com/a/18113368/492336 中概述的解决方案使用 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 连接到服务器以便它可以按需获取新行。

例如,如果表有 100 万行,是否会在 SqlDataAdapter::Fill 返回之前将所有行读取并写入DataTable 对象?

【问题讨论】:

  • 是的,查询返回的所有数据都会填入DataTable。您可以使用 where 子句修改查询以过滤数据
  • 它获取满足您提供的查询的所有数据。

标签: c# sql .net datagridview sqldataadapter


【解决方案1】:

限制通过 SQL 加载的行数可以定性地限制它们(WHERE...),也可以通过相当生硬的 LIMIT 子句来限制它们。您还可以使用DataAdapter 在“页面”或组中加载行 - 一次一点。这使用 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,而是使用表单/类一级。阅读下一页会给您一些选择:

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 仅显示当前组:

【讨论】:

  • 这个答案很详细,谢谢。所以我使用它的方式是获取所有数据,但毕竟有一种方法可以按需提供。
  • 可以结合SQL限制,如WHERE Active = True,然后在页面中加载那个子集。
【解决方案2】:

是的,它将创建对象并在您的网格视图上实现以显示您的所有数据,问题是您如何编写 SQL 查询,您可以使用一些 SQL 关键字如 TOP、LIMIT、OFFSET 来限制数据行.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-28
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多