2012-01-03 13 views
33

Próbuję utworzyć instrukcję LINQ, gdzie klauzula where pochodzi ze zmiennej. Na przykład:C# Linq gdzie klauzula jako zmienna

string whereClause = address.zip == 23456; 
var x = from something in someList where whereClause; 

Czy to możliwe? Nie mogę tego zmusić do działania.

Dzięki,

Aktualizuj - mój gdzie klauzula jest predefiniowany i będzie opierać się na danych wprowadzonych przez użytkownika, więc nie sądzę, że to będzie pracować dla mnie. Zasadniczo whereClause nie jest skonstruowany w metodzie, jest to parametr metody, która wykonuje LINQ. Nie wyjaśniłem, że dobrze tutaj jest lepszy przykład:

public void doLnq(string whereClause) 
{ 
    var x = from something in someList where whereClause; 
    dowork(x); 
} 

Aktualizacja - Wystarczy podsumować niektóre sugestie i scentralizować wszystko.

Nie mogę użyć przełącznika do wygenerowania klauzuli where, ponieważ istnieje wiele możliwości.

Dynamiczny post linq, który napisali niektórzy z was, wygląda obiecująco, ale mam problemy związane z linq do sql przy moim problemie z linq to objects.

i @sLaks po pominie MSDN http://msdn.microsoft.com/en-us/library/bb353734.aspx Mam problemy zastanawianie się, gdzie chodziło o użycie AsQueryable

dzięki,

+0

Er, nie. Klauzula where jest po prostu * nie * ciągiem znaków, jest to wyrażenie zwracające wartość logiczną. Z wyjątkiem ... zobacz link SLaksa! – sq33G

+0

@ sq33G ciąg znaków w tej sytuacji będzie "address.zip == 23456" Chciałbym użyć jako wyrażenia. Ciąg pochodzi od danych wprowadzonych przez użytkownika, dzięki czemu można wykonywać niestandardowe wyszukiwania. Czy to ma sens? – kds6253

+0

Zgaduję, że użytkownik wybiera pole (pole == wartość) z menu rozwijanego. Więc prawdopodobnie możesz użyć instrukcji switch do zbudowania Func , aby wysłać jako delegata Where. – sq33G

Odpowiedz

49

Trzeba montaż Expression<Func<T, bool>> i przekazać je do metody Where() rozszerzenia:

Expression<Func<T, bool>> whereClause = a => a.zip == 23456; 
var x = frSomeList.Where(whereClause); 

EDIT: Jeśli używasz LINQ to Objects, usuń słowo Expression stworzyć n zwykłego delegata.

+1

Z tagiem 'linq-to-objects', będzie * Wyrażenie * być właściwe? –

+0

zobacz aktualizację – kds6253

+0

@ kds6253: Następnie można przyjąć delegata jako parametr. Jeśli potrzebujesz użyć łańcucha, możesz użyć dynamicznego LINQ (ale będzie wolniej). – SLaks

9

to:

var query = from something in someList where whereClause; 

jest skrótem:

var query = someList.Where(something => whereClause); 

Zakładając someList jest IEnumerable<Address>, Where dotyczy Enumerable.Where Extension Method. Metoda ta oczekuje Func<Address, bool> które można zdefiniować następująco:

Func<Address, bool> whereClause = address => address.Zip == 23456; 
var query = someList.Where(whereClause); 
+0

zobacz aktualizację – kds6253

0

Aby zdefiniować klauzulę Where w środowisku wykonawczym, należy użyć kwerendy dynamicznej.

Scott Gu pisał wielki post o tym tutaj: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

nadzieję, że pomoże.

+0

Sprawdziłem poprzedni post i nie bardzo wiem, jak zastosować go do mojej sytuacji. Jestem stosunkowo nowy w tym, więc proszę o zachowanie mnie. Przykładem, którego użył, jest linq do Sql, a źródłem danych jest baza danych Northwind. Jak mogę to zmienić, aby działał z moim problemem Linq to Object? Raz znowu doceniam pomoc. – kds6253

3

Jak zaznaczył Richard, do tworzenia dynamicznych wyrażeń filtru można użyć biblioteki dynamicznego kwerendy. Podczas korzystania z Linq-To-Object najpierw przekonwertuj swój IEnumerable<T> na IQueryable<T>.Oto przykład (niekompletny):

using System.Linq.Dynamic; 

namespace System.Linq.Dynamic 
{ 
    public class Example 
    { 
    // Assuming some value is assigned to below field somewhere... 
    private IEnumerable<Address> m_Addresses; 

    public void FilterByZipCode(string zipCode) 
    { 
     var x = m_Addresses.AsQueryable().Where("Zip == @0", zipCode); 
     dowork(x); 
    } 
    } 

    public class Address 
    { 
    public String Zip { get; set; } 

    // More Properties... 
    } 
}