2012-04-25 45 views
6

Mam te 4 pola wyboru, które stanowią ciąg zmiennych saljes, kopie, bajty, erbjudes. Gdy są sprawdzane, otrzymują wartość "on".Contains(), jak odwrócić za pomocą lambda

Z tego powodu stworzyłem zmienną łańcuchową (p), która zawiera wszystkie liczby, które chcę uwzględnić w instrukcji LINQ. Powiedzmy, że jeśli wszystkie pola wyboru są zaznaczone, otrzymam ciąg znaków "1234", a jeśli zaznaczone zostaną tylko pola wyboru 2 i 4, wynik będzie wynosił "24".

W mojej bazie danych mam pole o nazwie "Typ", które jest typu int. Chcę, aby baza danych zawierała wszystkie wiersze mające wartość "Typ", które można znaleźć w ciągu znaków p.

Coś takiego (oczywiście mój kod nie działa, więc muszę chłopaki):

 var searchResult = from s in db.Ads select s; 
     string p = "1"; 

     if (saljes != "on") 
      p = p.Replace("1", ""); 
     if (kopes == "on") 
      p += "2"; 
     if (bytes == "on") 
      p += "3"; 
     if (erbjudes == "on") 
      p += "4"; 

     searchResult = searchResult.Where(s => p.Contains(s => s.Type.ToString()); 

Co ja troche trzeba zrobić, to odwrócone Zawiera(), ale w jaki sposób?

+0

Nie można użyć 'IEnumerable p'? Zawsze możesz "String.Join" go, jeśli potrzebujesz go w połączeniu, ale pozwoliłby ci większą kontrolę w odniesieniu do uzyskania indywidualnych wartości. Inną opcją jest użycie bitów: 'Int32 p;' i test '(p & 1)', '(p & 4)', itd. –

+0

Więc jeśli twój ciąg to '" 234 "' wartość '24' należy znaleźć w bazie danych? –

+1

Twoje pytanie jest dla mnie trochę niejasne - warto byłoby zobaczyć kilka przykładów tego, co chcesz osiągnąć dla różnych wartości "Typu". –

Odpowiedz

1

już Contains() jest 'odwrotne', jak opisano here:

int[] productList = new int[] { 1, 2, 3, 4 }; 

var myProducts = from p in db.Products 
       where productList.Contains(p.ProductID) 
       select p; 

Więc po prostu wypełnić listę:

var list = new List<int>(); 

if (saljes == "on") 
    list.Add(1); 
if (kopes == "on") 
    list.Add(2); 
if (bytes == "on") 
    list.Add(3); 
if (erbjudes == "on") 
    list.Add(4); 

var searchResult = db.Ads.Where(s => list.Contains(s.Type)); 
+1

Wielkie dzięki! Chociaż musiałem trochę zmodyfikować kod. Jeśli spróbowałem wyrażenia lambda wewnątrz Contains(), powiedział: "Nie można przekonwertować wyrażenia lambda na typ int, ponieważ nie jest to typ delegata". Chociaż jeśli piszę tylko searchResult = searchResult.Where (s => list.Contains (s.Type)); to działa dobrze. –

3

Nie wiadomo, co jest problem, ale to powinno działać:

searchResult = searchResult.Where(s => p.Contains(s.Type.ToString()); 

p jest stringiem i Contains(string value) oczekuje, że string będzie parametrem, więc nie potrzebujesz wyrażenia lambda.

1

Czy to wyrażenie to zrobi?

s => s.Type.ToString().ToCharArray().Except(p.ToCharArray()).Count() == 0 

E.g. jeśli s.Type jest 24 i p jest "234", wówczas s.Type jest zawarty w łańcuchu. Jeśli będziemy konwertować int do char-macierzy otrzymujemy

{'2', '4'} 

Ciąg konwertowany do char-tablicy jest

{'2', '3', '4'} 

Oznacza to, że cyfry int są wliczone w string. Tak więc cyfry int z wyjątkiem cyfr string dają pusty zestaw, który testujemy z Count() == 0.

{'2', '4'}.Except({'2', '3', '4'}) ==> { } 

Zamiast tworzyć string, chciałbym stworzyć List<char>

var p = new List<char>();    

if (saljes == "on") p.Add('1');    
if (kopes == "on") p.Add('2');    
if (bytes == "on") p.Add('3');    
if (erbjudes == "on") p.Add('4');    

Następnie wyrażenie staje

s => s.Type.ToString().ToCharArray().Except(p).Count() == 0 

jednak zdawać sobie sprawę z faktu, że to nie może być przekonwertowane na odpowiednią klauzulę SQL-where.Dlatego cała tabela będzie musiała zostać zeskanowana.

Powiązane problemy