2016-10-02 56 views
0

我正在嘗試編寫一個用於訂購IQueryable數據庫集合的通用擴展方法。 (還有更多的它,但是這是我塔克商的一部分。)使用表達式創建擴展方法

我想提供:

  1. 數據庫類(如客戶,僱主)
  2. 的LINQ表達爲列
  3. 列的類型(整型,字符串等)

我開始與一個類,應該包含這些信息,但我陷入瞭如何定義和使用表達式。

對於我的想法是這樣的用法,但不知道在哪裏,爲每列提供類型

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>一起工作。