web-dev-qa-db-ja.com

大量のデータでDataGridViewを埋める最良の方法

25,000個以上のレコードとそれぞれ21列を保持する2つのDataGridView(DGV)を持つウィンドウフォームがあります。 DataAdapterを使用してDBからのデータをそれぞれに正常にロードした後、forループを使用してDGVを単純に埋めてみました。どちらの方法でも、ほぼ同じ時間がかかりました。データが最初にDGVに入力されるときは時間がかかりすぎ(7分以上)、その後の時間ははるかに妥当です(約30秒)。だから私の質問は、平均で1分以下かかる大量のデータをDGVにロードするための最良の方法は何ですか?私はDGVの機能が本当に好きですが、Pushが駆り立てば、その機能の一部を放棄することになっても、別のテクノロジーを使用することをいとわないです。

21
Bkins

DataGridViewにデータを表示するには、基本的に3つの方法があります

  • 現在行っているように、ループで手動で行を作成します。お気づきのように、大量のデータがある場合は非常に非効率的です

  • ジョナサンのコメントで示唆されているように、DataGridViewの仮想モードを使用します。DGVは表示可能な行のみを作成し、ユーザーがスクロールすると内容を動的に変更します。必要なデータをDGVに提供するには、CellValueNeededイベントを処理する必要があります

  • データバインディングを使用します。これがはるかに簡単な方法です。 DataTableDbDataAdapterを使用してデータベースからのデータを入力するだけで、このDataTableをDGVのDataSourceプロパティに割り当てます。 DGVは自動的に列(AutoGenerateColumns = true)、または手動で作成できます(列のDataPropertyNameを、表示するフィールドの名前に設定する必要があります)。データバインドモードでは、DGVは仮想モードと同様に機能しますが、データソースからデータをフェッチするので、何もする必要がありません。多数の行でも非常に効率的です

34
Thomas Levesque

DataAdapterの代わりにDataReaderメソッドを使用できると思います。 DataReaderはソースからデータを読み取るだけなので、非常に効率的な一方向のコンポーネントであり、データテーブルにループを設定できます。

6
Nanda

10 000以上のような大量の行がある場合、

パフォーマンスリークを回避するために-データバインディングの前に以下を実行します。

dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing; 
//or even better .DisableResizing. 
//Most time consumption enum is DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders
dataGridView1.RowHeadersVisible = false; // set it to false if not needed

データバインド後、有効にすることができます。

2
okarpov

DataTableを使用してみてください。記入してください。次に、DataViewを使用します。これをDataGridView DataSourceに割り当てます。

//DataView dataView = new DataView(dataTable);
//this.Grid.DataSource = dataView;

大きなファイル(1秒あたり25000レコード、21列)の応答時間は非常に短くなります。私のテンプレートプログラムは、100 000行* 100列を読み込むのに7秒かかりました{愚かな内容->行番号を文字列として}

1
C. Lorphelin

これは私の問題を解決しました:

array<DataGridViewRow^>
    ^theRows = nullptr;
if (DG->Rows->Count == 0)//First Compilation
{
    int NUMROWS = xxx;
    theRows = gcnew array<DataGridViewRow^>(NUMROWS);
    for (int nr = 0; nr < DRH->Count; nr++)
        theRows[nr] = gcnew DataGridViewRow();
//Do not remove the two following
    DG->Rows->AddRange(theRows);
    DG->Rows->Clear();
}
else //Update
{

    theRows = gcnew array<DataGridViewRow^>(DG->Rows->Count);
    DG->Rows->CopyTo(theRows, 0);
    DG->Rows->Clear();

}
for(int nr=0;nr<theRows->Length;nr++)
{
    theRows [nr]->SetValues("val1", "val2");
}
DG->Rows->AddRange(theRows);
1
user2525774

これがあなたの求めていることとまったく同じかどうかはわかりませんが、最初に読み込むデータのサブセットを作成してから、検索機能を含めたいと思います。これは、Visual Studio 15とDataSources /データセットを使用して簡単に実行できます。ソリューションエクスプローラーで、dataset.xsdファイルを開きます。 DataSet.xsdという名前になります。問題のデータテーブルに移動します。右クリックして、クエリを追加します。私がよく行うことの1つは、クエリに「TOP 1000」を追加することです。したがって、select * from mytableはselect TOP 1000 * from mytableになります

最後に、フォームをダブルクリックして_loadメソッドを見つけ、「Fill」を変更して新しいクエリを使用します。これは例で最もよく示されるかもしれません:

コメントアウトしたコードの最初の行は、Vis Studがデフォルトで作成したコードです。 2番目は追加したもので、上位1000件のレコードのみを取得します。

        private void Form_Customers_Load(object sender, EventArgs e)
    {
        // TODO: This line of code loads data into the 'stage2DataSet.customers' table. You can move, or remove it, as needed.
        /* this.customersTableAdapter.Fill(this.stage2DataSet.customers); */
        this.customersTableAdapter.FillBy_Top_1000(this.stage2DataSet.customers);


    }
0
Joe Hayes