2015-12-08 8 views
5

私のデータテーブルにはすべての文字列が含まれていますが、いくつかの列には数値が入力されています。その数値列のdatatableでorderbyを実行すると、正しく順序付けされていません。注文前に私のテーブルは見た目decimalに変換して実行OrderBy

Name Account Department 
Kiran 1100 CSC 
Subbu 900  CSC 
Ram  500  CSC 
Raj  800  CSC 
Joy  400  CSC 

注文後に見える

Name Account Department 
Kiran 1100 CSC 
Joy  400  CSC 
Ram  500  CSC 
Raj  800  CSC 
Subbu 900  CSC 

私のコードのような:

public DataTable sortData(string columnName) 
{ 
    DataTable dt1=new DataTable(); 
    return dt1=dataMgr[DatabaseFileNames.ControlDatabase]["OrderedTableName"] 
       .Select("Department='CSC'") 
       .OrderBy(x=>!string.IsNullOrEmpty(x.Field<string>(columnName))) 
       .CopyToDataTable(); 
} 
+0

あなたの例では、 'columnName'に何を渡していますか?また、 'Account'列は数値列かどうか? – Jamiec

+1

私のテーブルにも空の値が入っているかもしれません。 –

+0

@MarcoForbergは、 "datatable"と言います - Imはデータのソース、つまりデータベースを尋ねています。 – Jamiec

答えて

1

:すべての比較についてです基本的に注文 -

public class MyComparer : IComparer<string> 
{ 
    private readonly string _columnName; 
    public MyComparer(string columnName) 
    { 
     _columnName = columnName; 
    } 

    public int Compare(string leftValue, string rightValue) 
    { 
     double leftDouble, rightDouble; 

     switch (_columnName) 
     { 
      case "Account": 
       if (Double.TryParse(leftValue, out leftDouble) && Double.TryParse(rightValue, out rightDouble)) 
       { 
        return leftDouble.CompareTo(rightDouble); 
       } 
       else 
       { 
        return String.Compare(leftValue, rightValue); 
       } 
      default: 
       return String.Compare(leftValue, rightValue); 
     } 
    } 
} 

...なぜ我々だけのカスタムComparerを書きません...その後、単に... [並べ替え基準に

public DataTable sortData(string columnName) 
{ 
    DataTable dt1=new DataTable(); 
    return dt1=dataMgr[DatabaseFileNames.ControlDatabase]["OrderedTableName"] 
       .Select("Department='CSC'") 
       .OrderBy(x => x.Field<string>(columnName) ?? String.Empty, 
          new MyComparer(columnName) 
        ) 
       .CopyToDataTable(); 
} 

をそれを追加...と我々は行われているとさえ他のデータ型を使用するためにそのソリューションを拡張することができますたとえば、 DateTime

+0

ありがとうMarco、あなたのソリューションはすべての私のシナリオのために働いています.. –

3

あなたOrderByは次のように多少になりますの

.OrderBy(x => double.Parse(x.Field<string>(columName))) 

共同あなたのすべての値が実際にはdoubleとして解析可能であることを前提としています。

数値以外の列に対しても機能させる必要がある場合は、列名に基づいて区別する必要はありません。

IComparer comparer = null; 
// instead of a switch/case you could also have a Dictionary<string, IComparer> for example... 
switch(columName) 
{ 
    case "Account": comparer = Comparer<double>.Default; 
        break; 
    default: comparer = Comparer<string>.Default; 
        break; 
} 

// so your OrderBy would look like this: 
.OrderBy(x => x, comparer) 

クリーナーソリューションは間違いなく正しいデータを持つことになります。多少のようになります(。。I.電子あなたがCOLUMNNAMEとIComparerの間にいくつかのマッピングを持っている必要があるだろう)

テーブル内の列の型。

+2

注意してください。列の名前順はパラメータとしてこのメ​​ソッドに渡されるので、名前列も同様に表示されます –

+0

@MarcoForbergちょうどそれが気に入っています。 – germi

+0

ユーザーは「名前」列も渡すことができます。コードはすべての列で機能するはずです –

2

あなたは単にパッドstring正しく動作するためにソートする0をリードしてint値を含むことができます(?10)

.OrderBy(x => x.Field<string>(columnName)?.PadLeft(10, '0') ?? "0") 

あなたは十分に大きいようにサイズを定義する必要がありますし、nullはそれをソートするためのいくつかの値("0"を使用する場合は最初に表示されます)。

私はこのことについてかなりの時間を考えて、私が思いついた解決策は、衝撃的な明白です
+0

それは賢明ですが、そのことは考えられませんでした。数字以外の列には問題があります。 – germi

+0

賢明なアイデアだが、データが名前でソートされている場合、これは問題を引き起こすのではないかと恐れている。 –

+1

@MarcoForberg、負の値または浮動小数点数の場合、これはうまくいきません。しかし、アイデアは明確でなければならず、いつでもそれを使用するかどうかを決定するのは営業担当者の責任です。 – Sinatr

関連する問題