自動ソートと互換性のLINQクエリのパフォーマンスについての戻り値の型
-
21-09-2019 - |
質問
これは本当に問題ではありませんが、私はしてください上のいくつかの入力をお願い申し上げ懸念よります。
Linq2Sqlを使用してWinformsのC#の.net3.5 [SP1]のVisual Studio 2008(より具体的には、 PLINQO の...これところで素晴らしいです!)。私は(行あたりのデータの約80bytesと)+/-データの19000行を返す結果セットを持っており、背景にデータ検索方法をプッシュし、それに応じてUIを更新することを選びました。これが正常に動作します。
私陵データ検索方法のためのさまざまなリターンタイプを使用する場合、しかし、私はいくつかのパフォーマンスの違いを気づきました。私は誰もがList<T>
またはIEnumarable<T>
を返す示唆して知っている、そしてそれにDataGridViewののデータソースを設定するが、残念ながらそれはオブジェクトに対してネイティブでソートをサポートしていません。周り掘り、いくつかの後、私はここにの MSDN上SortableBindingList<T>
を見つけました。私はそれを適用し、グリッド自体を移入するために、第2の下で取った - 。私はそれを並べ替えるには、列をクリックしたときしかし、それは第二の上に少しかかったかそこらの並べ替えを実装するために、
私は、
また、私はどんなにおけるグリッド編集/追加/削除を無効にしていることに留意してください。グリッドはデータを表示するための純粋です。他のCRUD操作は、現在選択された行(隠された主キー列)による対話形式で提供されます。
ここでは、両方の方法に使用されるコードである
の 1)SortableBindingList の
//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()
ルートを行くに既知の問題をお願い申し上げます。
looongクエリのU ....と謝罪をありがとうございました!
解決
ここにあなたの質問に私のテイクが(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;
});
}
1が実際にソートされているプロパティの種類にひねらの多くのの速い比較子を、提供するために、GetComparer()
から派生したクラスで、それを上書きすることができますので、あなたが見ることができるように、SortableBindingList<T>
は、仮想です。一般的な比較演算が4秒で(String
プロパティによって)10000件のレコードをソートしながら、例えば、専門的な比較子は70msで、同じ仕事をしてくれます。
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のような他のソースからインスピレーションを得た/コピーした投稿のコードなので、信用の多くは私のものではありません。私の唯一の貢献は比較演算を仮想化しましたが、私は少しグーグルでは、より良好な表面だろうと確信している、同じ考え方に基づいて、以前のソリューションます。