Получает ли SqlDataAdapter::Fill весь набор результатов или это делается по запросу?

Я пытался подключить 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 к серверу, чтобы он мог получать новые строки по запросу.

Например, если в таблице 1 миллион строк, будут ли все они извлечены и записаны в объект DataTable до возврата SqlDataAdapter::Fill?


person sashoalm    schedule 08.08.2016    source источник
comment
Да, все данные, возвращаемые запросом, будут заполнены в DataTable. Вы можете изменить запрос, используя предложение where, чтобы файлировать данные   -  person Dheeraj Kumar    schedule 08.08.2016
comment
Он получает все данные, которые удовлетворяют заданному вами запросу.   -  person Murray Foxcroft    schedule 08.08.2016


Ответы (2)


Ограничение количества строк, загружаемых через 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 для отображения только текущей группы:

person Ňɏssa Pøngjǣrdenlarp    schedule 08.08.2016
comment
Этот ответ очень подробный, спасибо. Таким образом, как я его использовал, он извлекал все данные, но в конце концов есть способ сделать это по запросу. - person sashoalm; 08.08.2016
comment
Вы можете комбинировать с ним ограничения SQL, например WHERE Active = True, а затем загружать это подмножество на страницах. - person Ňɏssa Pøngjǣrdenlarp; 08.08.2016

да, он создаст объект и будет реализован в вашем представлении сетки, чтобы показать все ваши данные, дело в том, что, как вы пишете SQL-запрос, вы можете ограничить строки данных, используя некоторые ключевые слова SQL, такие как TOP, LIMIT, OFFSET.

person Mohammad Aslam    schedule 08.08.2016