2016-04-13 11 views
0

レコードをDisplayOrderという列に基づいて昇順に並べ替える必要があります。 DisplayOrderがnullまたは0の場合、これらのレコードは最後に来るはずです。デフォルトでは、0またはnullのDisplayOrderがトップレコードとして表示されます。私はNULL DisplayOrderを持つすべてのレコードがNULLでないDisplayOrderを持つレコードの後に​​表示され、DisplayOrderを持つすべてのレコードが正しくソートされることを保証するDisplayOrderによってソートされていることを確認したいと思います。LINQ:NULL値を持つ昇順でレコードを最後にソート

ここで私はそれを達成しようとしていました。

public DataResponse<EKGType> GetByPage(KendoGridPost kendo) 
    { 
     try 
     { 
      DataResponse<EKGType> response = new DataResponse<EKGType>(ResponseType.Failure); 

      using (BusinessEntities context = new BusinessEntities()) 
      { 


       IEnumerable<EKGTypes> items = context.EKGTypes 
                .ToList() 
                .Select(c => MapEntity(c)) 
                .OrderBy(c => c.DisplayOrder.HasValue) 
                .ToList(); 

       response.Data = items.Skip(kendo.Skip).Take(kendo.PageSize).ToList(); 
       response.Count = items.Count(); 
       response.ResponseType = ResponseType.Success; 
      } 

      return response; 
     } 
     catch (Exception ex) 
     { 
      return HandleDataResponseException<EKGType>(ex); 
     } 
    } 

これは、最初にnull/0値を持つレコードを返します。私は過去1時間を探していて、SQLでそれを行う答えを見つけることができますが、linqではありません。

答えて

1

あなたはNULLとのそれらのためint.MaxValueか何かを使用することができます。

IEnumerable<EKGTypes> items = context.EKGTypes 
           .ToList() 
           .Select(c => MapEntity(c)) 
           .OrderBy(c => 
            c.DisplayOrder.HasValue 
            ? (c.DisplayOrder == 0 ? (int.MaxValue - 1) : c.DisplayOrder) 
            : int.MaxValue) 
           .ToList(); 

だから効果的にソートDisplayOrderによるそれらかのように彼らのDisplayOrderint.MaxValueDisplayOrder == 0を持つものであるかのようにDisplayOrder == nullを持つものが扱われますしながら、 DisplayOrderint.MaxValue - 1であった。
まず、0以外で0以外の値はすべてDisplayOrderでソートされ、その後に0、最後にNULLの値でソートされます。

+0

を入れた後? int.MaxValueエラーが発生しました "オペレータ '??'型 'bool'と 'int'のオペランドには適用できません " –

+0

あなたは' .HasValue'を削除しましたか?それだけです 'c.DisplayOrder ?? int.MaxValue' has not HasValue' –

+0

@RenéVogtその解決策はnull値で機能しますが、0も最後に来る必要はありますか? – itsme86

3

OrderBy()メソッドを使用すると、カスタム比較対象を渡すことができます。ような何か:

public class NullAndZeroLastComparer : IComparer<int?> 
{ 
    public int Compare(int? x, int? y) 
    { 
     int xValue = x.HasValue && x != 0 ? x.Value : int.MaxValue; 
     int yValue = y.HasValue && y != 0 ? y.Value : int.MaxValue; 
     return xValue.CompareTo(yValue); 
    } 
} 

は、その後、あなたはそれが好きで使用したい:

IEnumerable<EKGTypes> items = context.EKGTypes 
    .ToList() 
    .Select(c => MapEntity(c)) 
    .OrderBy(c => c.DisplayOrder, new NullAndZeroLastComparer()) 
    .ToList(); 
+0

その答えもそうですが、私はそのために新しいクラスを作るよりも、ロジックを直接 'OrderBy'に入れたいと思っています。とにかく+1 –