2012-12-03 12 views
5

Chcę przekazać dynamiczne wyrażenia lambda do poniższej funkcji, ale nie jestem pewien jak zdefiniować .Take() lub .OrderByDescending() na obiekcie wyrażenia. Jeśli chcę wywołać funkcję poniżej, a następnie chcę, aby móc to zrobić:Jak zdefiniować SELECT TOP przy użyciu LINQ z zapytaniem dynamicznym?

dbprovider.Query = (x => x.ConfigurationReference == "172.16.59.175") 
        .Take(100) 
        .OrderByDescending(x.Date) 
FindEntities(db, dbprovider.Query) 

Ale nie mogę (ta składnia jest nieprawidłowy). Jakieś pomysły?

public static List<T> FindEntities<T>(TrackingDataContext dataContext, System.Linq.Expressions.Expression<Func<T, bool>> find) where T : class 
{ 
    try 
    { 
     var val = dataContext.GetTable<T>().Where(find).ToList<T>(); 
     return val; 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
} 
+1

Twój obsługi wyjątku osiąga niczego przydatne, btw, i nie robić złe rzeczy (to traci StackTrace); powinieneś usunąć 'try' /' catch' - co powoduje, że cała metoda 'FindEntities' wygląda całkiem niepotrzebnie –

Odpowiedz

5

Parametr jest typu:

System.Linq.Expressions.Expression<Func<T, bool>> find 

Oznacza to, że może to zająć orzecznik (z klauzuli "gdzie"), a tylko predykatem. Zatem tylko nieco można przekazać tam jest filtr:

x => x.ConfigurationReference == "172.16.59.175" 

Aby zrobić to, co chcesz, trzeba by dodać resztę kodu w FindEntities, tak że staje się:

var val = dataContext.GetTable<T>().Where(find) 
       .OrderByDescending(x => x.Date).Take(100).ToList<T>(); 

(uwaga również, że Take powinien być naprawdę poOrderByDescending)

Jeden sposób mógłby zrobić byłoby:

public static List<T> FindEntities<T>(TrackingDataContext dataContext, 
    System.Linq.Expressions.Expression<Func<T, bool>> find, 
    Func<IQueryable<T>, IQueryable<T>> additonalProcessing = null 
) where T : class 
{ 
    var query = dataContext.GetTable<T>().Where(find); 
    if(additonalProcessing != null) query = additonalProcessing(query); 
    return query.ToList<T>(); 
} 

i zadzwonić:

var data = FindEntities(db, x => x.ConfigurationReference == "172.16.58.175", 
    q => q.OrderByDescending(x => x.Date).Take(100)); 

Jednak, szczerze mówiąc nie jestem pewien, o co chodzi z tym byłoby ... dzwoniący mógł zrobić to wszystko sami lokalnie bardziej wygodnie, bez użycia FindEntities w ogóle. Wystarczy:

var data = db.GetTable<T>() 
      .Where(x => x.ConfigurationReference == "172.16.58.175") 
      .OrderByDescending(x => x.Date).Take(100).ToList(); 

lub nawet:

var data = db.SomeTable 
      .Where(x => x.ConfigurationReference == "172.16.58.175") 
      .OrderByDescending(x => x.Date).Take(100).ToList(); 

lub po prostu:

var data = (from row in db.SomeTable 
      where row.ConfigurationReference == "172.16.58.175" 
      orderby row.Date descending 
      select row).Take(100).ToList(); 
Powiązane problemy