2016-10-02 12 views
0

IQueryableデータベースコレクションを注文するための汎用拡張メソッドを作成しようとしています。 (そこによりますが、これは私がsが上挟むだ部分です。)私が提供したい式を使用した拡張メソッドの作成

  1. データベースクラス(例えば顧客、雇用者を)
  2. 列のLINQ式は
  3. 列の型(int型、文字列、など。)

私はクラスで始まっているはず情報を含んでいますが、私は表現を定義して消費する方法に固執しています。私はこのような何かを考えています使用方法については

はなく、列ごとに種類を提供する場所がわから

その後
var sortedList = queryable.MyCustomSortMethod<User>(item => new List<SortItem> 
    { item.Column_Name, "ASC" },  //string 
    { item.Column_BirthYear "DESC" }, //int 
    { item.Column_BirthDate, "ASC" } //date 
} 

私は、セレクタとその方向を指定するには、クラスを持っている

public class SortItem<TEntity> 
{ 
    public Expression<Func<T> SortFieldSelector<T> { get; set; } 
    public SortDirectionType SortDirectionType { get; set; } 
    //but how to provide column type 
}  

次に、このような拡張方法

public static IQueryable<TEntity> MyCustomSortMethod(
    this IQueryable<TEntity> queryable, 
    List<SortItem<TEntity> selectors) 
{ 

    foreach (var selector in selectors) { 

     if(selector.Direction == "asc") 
      queryable = queryable.OrderBy(selector.SortFieldSelector); 
     else 
      queryable = queryable.OrderByDescending(selector.SortFieldSelector); 
    } 
    //I need to specify the type of the OrderBy column somehow 
    // otherwise compiler errors with "arguments cannot be inferred..." 

    return queryable; 

} 

ウサギの穴I探検はかなり醜くなってきており、私はそれを行う簡単な方法があると確信しています。

拡張メソッドを使用する必要があるという事実は堅固な要件ですが、残りの部分はソリューションを簡素化する場合は柔軟性があります。

ご迷惑をおかけして申し訳ありません。

+0

何がポイントですか?それは 'queryable.OrderBy(item => item.Column_Name).ThenByDescending(item => item.Column_BirthYear).ThenBy(item => item.Column_BirthDate)' –

+0

@Thomasよりも使いやすいとは思われません。この場合は行いません。拡張メソッドには、リストが空の場合(およびいくつかの追加パラメータに基づいて)、いくつかの追加ロジックがあります。私は、呼び出しメソッドでコードの重複を避けるために、拡張メソッドに含まれているロジックを維持しようとしています。 – zeeqzaq

答えて

1

あなたはこのような何か行うことができます。

public class SortItem<TEntity> 
{ 
    public Expression<Func<TEntity, object>> Selector { get; } 
    public ListSortDirection Direction { get; } 

    public SortItem(Expression<Func<TEntity, object>> selector, ListSortDirection direction) 
    { 
     Selector = selector; 
     Direction = direction; 
    }  
} 


public static IQueryable<TEntity> MyCustomSortMethod<TEntity>(
    this IQueryable<TEntity> queryable, 
    IEnumerable<SortItem<TEntity>> selectors) 
{ 
    foreach (var selector in selectors) 
    { 
     IOrderedQueryable<TEntity> ordered = queryable as IOrderedQueryable<TEntity>; 
     if (ordered == null) 
     { 
      if (selector.Direction == ListSortDirection.Ascending) 
       queryable = queryable.OrderBy(selector.Selector); 
      else 
       queryable = queryable.OrderByDescending(selector.Selector); 
     } 
     else 
     { 
      if (selector.Direction == ListSortDirection.Ascending) 
       queryable = ordered.ThenBy(selector.Selector); 
      else 
       queryable = ordered.ThenByDescending(selector.Selector); 
     } 
    } 
    return queryable; 
} 

ThenBy代わりのOrderedByの使用を注意してください。あなたは毎回OrderByを使用している場合、それはだけではなく、それを完了したのは、前の順序を上書きします)

免責事項:私はそれを試していないので、実際にFunc<TEntity, object>で動作するかどうかはわかりません。

関連する問題