2012-07-05 28 views
10

Entity Framework 4'ü kullanarak, üye isimlerinin bir koleksiyonuna dayalı olarak dinamik sıralama gerçekleştirmeye çalışıyorum. Temel olarak, kullanıcı sıralanacak alanları ve sıralama sırasını seçebilir. İfade ağacı örneklerine baktım ve bunu bir araya getiremedim. aşağıdaki gibiÇalışma zamanı sıralama için nasıl bir ifade ağacı oluştururum?

public List<string> sortColumns; 
sortColumns = new List<string>(); 

/// Example subset of video fields. The collection will vary. 
sortColumns.Add("Width"); 
sortColumns.Add("Height"); 
sortColumns.Add("Duration"); 
sortColumns.Add("Title"); 

Video sınıfı tanımlanır:: sütun adları

Koleksiyonu: İşte bazı detaylar yapmak istiyorum ne

public class Video 
{ 
    public string Title { get; set; } 
    public int Width { get; set; } 
    public int Height { get; set; } 
    public float Duration { get; set; } 
    public string Filename { get; set; } 
    public DateTime DateCreated { get; set; } 
    . 
    . 
    . 
} 
public List<Video> Videos; 

inşa etmek sortColumns topluluğunda numaralandırmak olduğunu çalışma zamanında bir ifade ağacı. Ayrıca, kullanıcı ya artan ya da azalan sıralama belirtebilir ve ifade ağacının da işlemesi gerekir.

Ben VS 2008 için Dinamik LINQ kütüphanesini çalıştı, ama

(I. Yanlış bir şey yapıyor olabilir) alt çizgidir dinamik bir ifade ağacı ihtiyaç olduğunu VS 2010 yılında çalışmak için görünmüyor Video koleksiyonunu kullanıcı girdisine göre sıralayın. Herhangi bir yardım takdir edilecektir.

cevap

14

İlk önce @Slace'in here yazdığı OrderBy uzantı yöntemine gereksiniminiz vardır. Mükemmel bir kod parçası ve çözümün en zor kısmı için Slace numaralı kredi! Sizin durumunuza uygun çalışmak için biraz değişiklik yaptım:

Listeyi sıralamak için bir yöntem oluşturun. Birkaç şey aşağıda yöntemde not:

  1. List<string> ifade ağaçlar yapmayız bir IQueryable<string>Enumerable beri operatörler dönüştürülür. ters sırada sıralama sütunların listesini
  2. yöntemi yinelenir

(Listede en yüksek sıralama önceliği ilk öğe vermek istiyorum varsayarak).

private void PrintVideoList(IEnumerable<string> sortColumns, ListSortDirection sortOrder) 
{ 
    var videos = this.GetVideos(); 
    var sortedVideos = videos.AsQueryable(); 

    foreach (var sortColumn in sortColumns.Reverse()) 
    { 
     sortedVideos = sortedVideos.OrderBy(sortColumn, sortOrder); 
    } 

    // Test the results 
    foreach (var video in sortedVideos) 
    { 
     Console.WriteLine(video.Title); 
    } 
} 

Sonra böyle bir yöntemi kullanmak mümkün olmalıdır:

// These values are entered by the user 
var sortColumns = new List<string> { "Width", "Title", "Height" }; 
var sortOrder = ListSortDirection.Ascending; 

// Print the video list base on the user selection 
this.PrintVideoList(sortColumns, sortOrder); 
+0

(http://msdn.microsoft.com/en-us/library/system .componentmodel.listsortdirection.aspx) enum;) –

+0

@BennorMcCarthy Harika! Teşekkürler. Cevabı güncelleyeceğim. –

+0

'@ Kevin - Tam olarak ne istedim, teşekkürler! – James

0

Ben Kevin gerekli tam olarak ne var. Fark ettiğim, siparişi kullanırsanız sadece son sipariş seçimini almanızdır.

benimkine bu yöntemi (ThenBy) eklenir ve iş gibi görünüyor iyi

public static IQueryable<T> ThenBy<T>(this IQueryable<T> source, string sortProperty, ListSortDirection sortOrder) 
    { 
     var type = typeof(T); 
     var property = type.GetTypeInfo().GetDeclaredProperty(sortProperty); 
     var parameter = Expression.Parameter(type, "p"); 
     var propertyAccess = Expression.MakeMemberAccess(parameter, property); 
     var orderByExp = Expression.Lambda(propertyAccess, parameter); 
     var typeArguments = new Type[] { type, property.PropertyType }; 
     var methodName = sortOrder == ListSortDirection.Ascending ? "ThenBy" : "ThenByDescending"; 
     var resultExp = Expression.Call(typeof(Queryable), methodName, typeArguments, source.Expression, Expression.Quote(orderByExp)); 

     return source.Provider.CreateQuery<T>(resultExp); 
    } 
Zaten tanımlanmış ListSortDirection kullanabilirsiniz
İlgili konular