2009-06-12 12 views
17

Chciałbym ponownie użyć wyrażeń z powodów SUCHYCH, ale jak mogę ponownie użyć wyrażeń w instrukcji LINQ?Jak mogę ponownie użyć wyrażeń w instrukcjach LINQ?

np.

mam

public static class MyExpressions { 
    public static Expression<Func<Product,bool>> IsAGoodProduct() { 
     return (p) => p.Quality>3; 
    } 
} 

i chciałby używać, że w sprawozdaniu LINQ, więc

var goodProds = from p in dataContext.Products 
        where ????? // how do I use IsAGoodProduct here? 
        select p; 

Oczywiście, można korzystać z funkcji IQueryableExtension.Where, ale która stałaby łączy i innych funkcji dużo brzydszej dla bardziej złożonych zapytań.

Czy to możliwe, czy jest to ograniczenie LINQ?

Odpowiedz

21

Jeśli przejść z cukrem składniowej LINQ to możliwe:

var goodProds = dataContext.Products.Where(MyExpressions.IsAGoodProduct()); 

Bez niej nie jest możliwe.

Nic nie stoi na przeszkodzie, aby połączyć dwa style, aby zbudować pojedyncze zapytanie.

Przykład:

var goodProds = from p in dataContext.Products 
             .Where(MyExpressions.IsAGoodProduct()) 
        group p by p.Category into g 
        select new {Category = g.Key, ProductCount = g.Group.Count()}; 
+1

@Gary - mam nadzieję, że nie masz nic przeciwko, że dodałem przykład, aby było wyraźniejsze. – tvanfosson

+0

Nie, to świetnie :) –

+0

Co z użyciem: "where IsAGoodProduct() .Kompiluj(). Invoke()" – Razzie

1

Nawiasem mówiąc, mam natknąć tym useful article która wyjaśnia, jak można tworzyć dynamiczne zapytań LINQ, który funkcjonuje jako referencyjne owinięte wyrazu przy użyciu niestandardowego ToExpandable() metodę rozszerzenia. Dostarczone rozwiązanie może być używane w różnych częściach kwerendy LINQ przy jednoczesnym zachowaniu użycia comprehension syntax zamiast stosowania składni lambda.

2

Mieliśmy ten sam problem. Nie jest obsługiwany po wyjęciu z pudełka i jest poważnym problemem dla aplikacji LOB. Skończyło się na napisaniu artykułu o projekcie kodu dotyczącego ponownego użycia wyrażeń LINQ, w tym bardzo małego narzędzia o nazwie LinqExpressionPrjection, które umożliwia ponowne wykorzystanie w prognozach (w tym na typy anonimowe).

Znajdź artykuł here.

Możesz pobrać zespół do ponownego wykorzystania rzutowania jako nuget package, a źródło na CodePlex.

Minęło trochę czasu od twojego posta. Mam nadzieję, że nadal będzie dla ciebie pomocna. Jeśli nie, może dla innych czytających ten wątek.

3

Miałem ten sam problem i chciałem zachować możliwość stosowania metod rozszerzających w składni zapytania (tak jak w zwykłych obsługiwanych funkcjach ...). Rozwiązaniem może być this library.

Po prostu zaimplementowano metodę ponownego użycia dwa razy, raz do użytku ogólnego i raz do zapytania.

public static class MyFunctions { 
    [InjectLambda] 
    public static bool IsAGoodProduct(Product product) { 
     return product.Quality>3; 
    } 
    public static Expression<Func<Product,bool>> IsAGoodProduct() { 
     return (p) => p.Quality>3; 
    } 
} 

Rzeczywiste zapytanie może wyglądać tak, jak powinno.

var goodProds = from p in dataContext.Products.ToInjectable() 
       where p.IsAGoodProduct() 
       select p; 

ToInjectable połączenie tworzy lekki proxy, które zastępuje połączenia IsAGoodProduct metody (jeśli oznaczony odpowiednio) z pożądanym ekspresji lambda.W ten sposób można używać metod rozszerzeń wszędzie tam, gdzie w zapytaniu - działają również sparametryzowane metody.

Powiązane problemy