0

私は今、私たちの非常に古いシステムに問題を抱えています。(!7歳以上で、構造を大幅に変更するための予算とリソースがないため、古いロジックをできるだけ改善することにしました。!)

独自のグリッドコントロールが作成されています。基本的には通常のASP.NETグリッドのようで、要素を追加、変更、削除できます。

問題は、グリッドにBindGrid()メソッドがあり、さらに使用するために、データソーステーブルの行がにコピーされることDataRow[]です。を保持する必要がありDataRow[]ますが、テーブルから配列にソースをコピーするための最良の方法を実装したいと思います。

現在の解決策:

DataRow[] rows = DataSource.Select("1=1", SortOrderString);

これまでに経験したように、特定の並べ替えを取得する必要がある場合は、それが最善の方法である可能性があります(より高速な方法があるかどうかにも関心があります)。

ただし、SortOrderが不要な簡略化されたページがいくつかあります。

したがって、ソート順用となし用の2つの方法を作成できます。本当の問題は2番目の問題です。

 DataRow[] rows = DataSource.Select("1=1");

とても遅いから。私はいくつかのテストを行いましたが、CopyTo()ソリューションよりも15倍遅いです:

DataRow[] rows = new DataRow[DataSource.Rows.Count];
DataSource.Rows.CopyTo(rows,0);

より高速な方法を使用したいのですが、テストを行ったときに古い関数がクラッシュしただけです。他にも違いがあるようです。私が今気付いたのは 、Select()がRowChangesが受け入れられるように行を取得することです。

したがって、行を削除し、AcceptRowChanges()残念ながらそれはできません)を使用しない場合、Select("1=1")その行はにありますDataSourceが、にはありませんDataRow[]

単純な.CopyTo()列があり、それは私にとって悪いニュースです。

私の質問は次のとおりです。

1)Select( "1 = 1")は、RowChangesによって行を取得するための最良の方法ですか?(6歳くらいなので少し疑わしいです)

2)1)がそうでない場合、.Select( "1 = 1")よりも同じ結果でより高速な方法を実現することは可能ですか?

アップデート:

これが非常に基本的なテストアプリで、スピードテストに使用したものです。

DataTable dt = new DataTable("Test");

dt.Columns.Add("Id", typeof (int));
dt.Columns.Add("Name", typeof(string));

for (int i = 0; i < 10000; i++)
{
    DataRow row = dt.NewRow();
    row["ID"] = i;
    row["Name"] = "Name" + i;
    dt.Rows.Add(row);
}

dt.AcceptChanges();
DateTime start = DateTime.Now;

DataRow[] rows = dt.Select();

/*DataRow[] rows = new DataRow[dt.Rows.Count];
dt.Rows.CopyTo(rows,0);*/

Console.WriteLine(DateTime.Now - start);
4

1 に答える 1

1

Select引数なしで呼び出すことができDataRow[] allRows = DataSource.Select();ます:"1=1"無意味なRowFilter.

別の方法は、 を使用Linq-To-DataSetして順序付けおよびフィルタリングすることDataTableです。それはより効率的ではありませんが、より読みやすく、保守しやすいものです。

実例や測定結果はまだありませんが、ある場合はない場合よりもコストがかかることRowFilterは明らかです。は次のように実装されています。"1=1"Select

public Select(DataTable table, string filterExpression, string sort, DataViewRowState recordStates)
{
    this.table = table;
    this.IndexFields = table.ParseSortString(sort);
    this.indexDesc = Select.ConvertIndexFieldtoIndexDesc(this.IndexFields);
    // following would be omitted if you would use DataSource.Select() without "1=1"
    if (filterExpression != null && filterExpression.Length > 0)
    {
        this.rowFilter = new DataExpression(this.table, filterExpression);
        this.expression = this.rowFilter.ExpressionNode;
    }
    this.recordStates = recordStates;
}

現在受け入れられていない行も選択できるようにしたい場合は、次のオーバーロードを使用できますSelect

DataRow[] allRows = DataSource.Select("", "", DataViewRowState.CurrentRows | DataViewRowState.Deleted);

AcceptChangesこれにより、まだ呼び出されていない場合でも、削除された行を含むすべての行が選択されます。

于 2012-09-17T10:21:07.113 に答える