2012-11-21 24 views
8

Son kullanıcının döndürülen raporun sıralama düzeni için birden fazla alan seçtiği bir raporlama arayüzüm var. Sorun şu ki, bir sıralama alanları listesiyle yinelemediğim için gerçekten OrderBy/ThenBy yöntemlerini zincirleyemiyorum. Böyle bir şey düşünüyorum:Program aracılığıyla zinciri OrderBy/ThenBy LINQ/Entity Framework kullanarak

foreach (string sort in data.SortParams) 
{ 
    switch (sort) 
    { 
     case "state": 
      query = query.ThenBy(l => l.RegionCode); 
      break; 
     case "type": 
      query = query.ThenBy(l => l.Type); 
      break; 
     case "color": 
      query = query.ThenBy(l => l.Color); 
      break; 
     case "category": 
      query = query.OrderBy(l => l.Category); 
      break; 
    } 
} 

(Not:. Bu yalınlık sağlamak için ilk sıralama madde olup olmadığını belirlerken anahtarı kaldırdık) bir topluluk içinde yineleme için nasıl

Herhangi bir düşünce sıralama düzenini belirlemek için?

cevap

15

Sen bir başlangıç ​​"tohum" OrderBy kullanırsanız istediğini yapabilirdi: Oluşturmak OrderBy çağırmanız gerekir

EDIT bir IOrderedEnumerable (veya IOrderedQueryable) ilk ThenBy maddeleri eklemeden önce:

var orderedQuery = query.OrderBy(l => 0); 
foreach (string sort in data.SortParams) 
{ 
    switch (sort) 
    { 
     case "state": 
      orderedQuery = orderedQuery.ThenBy(l => l.RegionCode); 
      break; 
     case "type": 
      orderedQuery = orderedQuery.ThenBy(l => l.Type); 
      break; 
     case "color": 
      orderedQuery = orderedQuery.ThenBy(l => l.Color); 
      break; 
     case "category": 
      orderedQuery = orderedQuery.ThenBy(l => l.Category); 
      break; 
    } 
} 
query = orderedQuery; // cast back to original type. 

daha esnek bir şey bu uzantıyı oluşturduk this answer

+0

Reklam öğesi, ancak bunun, sorgu performansını etkileyip etkilemediğini kontrol etmesi gerekiyor. İndeks kullanımını engelleyebilir. – usr

+1

Bu benim için bir çekicilik gibi çalıştı. İlk başta yukarıdaki gibi aynı kodu vardı, ancak ilk 'OrderBy() 'için varsayılan bir sütun seçmek zorunda kaldı - Ben orada yerine 0 koyabileceğini bilmiyordum. 0, nihai SQL sorgusunun her satır için 0 değerine sahip olan fazladan bir sütunla çıkmasına neden olur, sonra bu sıraya göre sıralanır, kukla sıralama elde edilir, sonra zincirdeki tüm sütunları uygular 'ThenBy()' s 'eklediniz. Teşekkürler! – BeemerGuy

+0

'OrderBy (l => 0)' öğesini çağırırken ArgumentOutOfRangeException öğesini alıyorum. [İşte] (https://pastebin.com/raw/TZQ9g8Es) 'StackTrace'. – Shimmy

-1

Tümünü bir arada kullanıyor Linq sorgusu okunabilirlik açısından en iyi seçenek değil. Sorgunuzu bellekte oluşturmak için IQueryable kullanırım. Benzer bir anahtar deyim kullanın (ancak IQueryable ile) ve sonra da sunucuda istenen sorguyu yürütmek için .ToList (yani numaralandırın) yapın.

+1

Teşekkürler, ama 'query' var aslında bir IQueryable; Sorun, OrderBy ve ThenBy komutları ile ilgilidir. ThenBy sadece bir OrderBy'ye ilk zincirlendiğinde kullanılabilir. – acullen72

+1

Aşağı oy hakkında açıklama için bakım !! ???????? – daehaai

1

kontrol isterseniz Söz belirtildiği gibi yöntemler aynı sorunu çözmek için: Bu uzatma yöntemleri sadece önceki ifade kontrol

foreach (string sort in data.SortParams) 
{ 
    switch (sort) 
    { 
     case "state": 
      query = query.AppendOrderBy(l => l.RegionCode); 
      break; 
     case "type": 
      query = query.AppendOrderBy(l => l.Type); 
      break; 
     case "color": 
      query = query.AppendOrderBy(l => l.Color); 
      break; 
     case "category": 
      query = query.AppendOrderBy(l => l.Category); 
      break; 
    } 
} 

REMARK:

public static class QueryableExtensions 
{ 
    public static IOrderedQueryable<T> AppendOrderBy<T, TKey>(this IQueryable<T> query, Expression<Func<T, TKey>> keySelector) 
     => query.Expression.Type == typeof(IOrderedQueryable<T>) 
     ? ((IOrderedQueryable<T>) query).ThenBy(keySelector) 
     : query.OrderBy(keySelector); 

    public static IOrderedQueryable<T> AppendOrderByDescending<T, TKey>(this IQueryable<T> query, Expression<Func<T, TKey>> keySelector) 
     => query.Expression.Type == typeof(IOrderedQueryable<T>) 
      ? ((IOrderedQueryable<T>)query).ThenByDescending(keySelector) 
      : query.OrderByDescending(keySelector); 
} 

söz konusu kodu daha sonra refactored olabilir ifade ağacı OrderBy veya ThenBy kullanılıp kullanılmayacağını belirlemek için, aralarında başka hiçbir ifadeye izin verilmez. Bunu da ele almak istiyorsanız, istemediğiniz tüm yükü ekleyebilecek tam bir ağaç boyunca yürümeniz gerekecek :)

İlgili konular