0

これは実際には問題ではありませんが、さらに懸念事項があるので、ご意見をいただければ幸いです。

Winforms C# .net3.5[sp1] Linq2Sql を使用した Visual Studio 2008 (より具体的にはPLINQO ...これは素晴らしいです!)。+/- 19000 行のデータ (行あたり約 80 バイトのデータ) を返す結果セットがあり、データ取得メソッドをバックグラウンドにプッシュし、それに応じて UI を更新することを選択しました。これはうまくいきます。

ただし、Ling データ取得メソッドにさまざまな戻り値の型を使用すると、パフォーマンスが異なることに気付きました。誰もがList<T>orIEnumarable<T>を返し、DataGridView のデータソースをそれに設定することを提案していることは知っていますが、残念ながら、オブジェクトのネイティブな並べ替えはサポートされていません。いくつか掘り下げた後、MSDN here を見つけSortableBindingList<T>まし。私はそれを適用し、グリッドはそれ自体を設定するのに1秒もかかりませんでした-しかし、列をクリックして並べ替えると、並べ替えを実装するのに1秒強かかりました.

次に、DataTable ルートに進むことにしましたが、ToDataTable メソッドが削除されていることがわかりましたが、さらに掘り下げた後、このMSDN 記事で実装する方法を見つけました。それを適用した後、取得にグリッドにデータを入力するのに約 2 秒かかることがわかりましたが、その後の並べ替え (19000 行で!) は瞬時に行われました!! 当然、私はこのアプローチに固執しました。

また、グリッド内編集/追加/削除を無効にしたことにも注意してください。グリッドは、純粋にデータを表示するためのものです。その他の CRUD 操作は、現在選択されている行 (非表示の主キー列) に従って、ダイアログ フォームによって提供されます。

両方の方法で使用したコードは次のとおりです。

1) ソート可能なバインディング リスト

    //declare private member
    private SortableBindingList<PdtAllocation> listAlloc = null;

    private void RefreshData() {
        bcsDataContext ctx = new bcsDataContext();
        try {
            listAlloc = new SortableBindingList<PdtAllocation>(ctx.PdtAllocation.ToList());
        }
        catch (Exception) {
            throw;
        }
        finally {
            ctx.Dispose();
        }

        dataGridView1.DataSource = listAlloc;
    }

2) CopyToDatatable

    //declare private member
    private DataTable dt = null;

    private void RefreshData() {
        dt = new DataTable();
        bcsDataContext ctx = new bcsDataContext();
        try {
            ctx.PdtAllocation.CopyToDataTable(dt, LoadOption.PreserveChanges);
        }
        catch (Exception) {
            throw;
        }
        finally {
            ctx.Dispose();
        }

        dataGridView1.DataSource = dt;
    }

これはおそらく「質問と回答」のケースのように思えることはわかっていますが、あなたの意見と、CopyToDataTable()ルートに進む際の既知の問題を教えていただければ幸いです。

ありがとうございます....そして長いクエリをお詫びします!

4

1 に答える 1

1

これがあなたの質問に対する私の見解です(SortableBindingListルートをたどります)。

一般的なリフレクション ベースの並べ替えアルゴリズムを使用しましたか? 私は最初にこれを行いましたが、パフォーマンスは本当に悪かったです。最後に、次の解決策を思いつきました。デフォルトの並べ替えを提供しますSortableBindingList<T>が、派生クラスに特殊な並べ替えを実装する可能性も残します。

ここにいくつかのコードがあります。

SortableBindingList<T>.ApplySortCore()

protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
    // Check if the sorted property implements IComparable
    ...

    List<T> itemsList = (List<T>)this.Items;

    Comparison<T> comparer = GetComparer(prop);

    itemsList.Sort(comparer);

    if (direction == ListSortDirection.Descending)
    {
        itemsList.Reverse();
    }

    ...
    // Set sort state (is sorted, sort property, sort dir)
}

ジェネリックSortableBindingList<T>は、基本的なリフレクション ベースのソーターを提供します。

protected virtual Comparison<T> GetComparer(PropertyDescriptor prop)
{
    return new Comparison<T>(delegate(T x, T y)
    {
        if (prop.GetValue(x) != null)
            return ((IComparable)prop.GetValue(x)).CompareTo(prop.GetValue(y));
        else if (prop.GetValue(y) != null)
            return -1 * ((IComparable)prop.GetValue(y)).CompareTo(prop.GetValue(x));
        else
            return 0;
    });
}

ご覧のとおり、は仮想であるため、実際にソートされるプロパティの型に微調整されたはるかに高速な比較機能を提供するために、GetComparer()から派生したクラスでそれをオーバーライドできます。たとえば、一般的な比較機能は (プロパティによって) 10000 レコードを 4 秒で並べ替えましたが、特殊な比較機能は同じ作業を 70 ミリ秒で実行しました。SortableBindingList<T>String

class CustomerList : SortableBindingList<Customer>
{
    protected override Comparison<Customer> GetComparer(PropertyDescriptor prop)
    {
        Comparison<Customer> comparer = null;
        switch (prop.Name)
        {
            case "FirstName":
                comparer = new Comparison<Customer>(delegate(Customer x, Customer y)
                {
                    string xx = (null == x) ? null : x.FirstName;
                    string yy = (null == y) ? null : y.FirstName;
                    return String.Compare(xx, yy);
                });
                break;
            ...
        }
        return comparer;
    }
}

最後の注意: 投稿されたコードの多くは、SO や Microsoft などの他のソースからコピー/インスピレーションを得たものであるため、クレジットは私のものではありません。私の唯一の貢献は比較機能を仮想化することでしたが、少しグーグルで検索すると、同じアイデアに基づく以前のソリューションがより適切に表示されると確信しています。

于 2009-11-19T16:28:25.457 に答える