6

I have these 4 checkboxes, which constitute the string variables saljes, kopes, bytes, erbjudes. When they are checked they get the value "on".

From this I put together a string variable (p) that contains all the numbers I want to include in the LINQ-statement. Let say if all the checkboxes are checked, i would get a string that is "1234", and if only checkbox 2 and 4 are checked, it would result in "24".

In my database I have a field called "Type" which is of type int. I want to tell the database to include all the rows that have a "Type" value that can be found in the string p.

Something like this (of course my code doesn't work, therefore I need you guys):

        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());

What I kinda need to do is a reversed Contains(), but how?

Daniel Mann
  • 57,011
  • 13
  • 100
  • 120
Mikael Edebro
  • 241
  • 2
  • 13
  • You can't use `IEnumerable p`? You can always `String.Join` it if you need it combined, but would allow you more control with regards to getting individual values. The other option is to use bits: `Int32 p;` and test `(p & 1)`, `(p & 4)`, etc. – Brad Christie Apr 25 '12 at 13:31
  • So if your string is `"234"` a value of `24` should be found in your db? – Olivier Jacot-Descombes Apr 25 '12 at 13:32
  • 1
    Your question is a little unclear to me -- it would be useful to see a few examples of what you want to have happen for various "Type" values. – Nate Kohl Apr 25 '12 at 13:35

3 Answers3

3

Not clear what the problem is, but this should work:

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

p is string and Contains(string value) expects string as parameter, so you don't need lambda expression.

Renatas M.
  • 11,694
  • 1
  • 43
  • 62
1

Contains() already is a 'reversed IN', as described here:

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

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

So simply fill a 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));
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • 1
    Thanks alot! Although I had to modify the code a bit. If I tried the lambda expression within the Contains() it said "Cannot convert lambda expression to type int because it is not a delegate type". Although if i only write searchResult = searchResult.Where(s => list.Contains(s.Type)); it works fine. – Mikael Edebro Apr 25 '12 at 13:48
1

Would this expression do it?

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

E.g. if s.Type is 24 and p is "234" then s.Type is included in the string. If we convert the int to a char-array we get

{'2', '4'}

The string converted to a char-array is

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

It means that the digits of the int are all included in the string. So the int digits except the string digits yield an empty set that we test with Count() == 0.

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

Instead of creating a string, I would create a 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');               

Then the expression becomes

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

However, be aware of the fact that this cannot be converted to an appropriate SQL-where clause. Therefore the whole table will have to be scanned.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188