23

New to LINQ and not sure on the correct syntax for what I want to do.

I have a "Blocklist", an array or list (could be either) of bad codes that I don't want put into this new "keys" list that I am making

currently...

var keys = (from s in context.Keys
            where s.Code != "BadCode1"
            where s.Code != "BadCode2"
            where s.Code != "BadCode3"
            where s.Code != "BadCode4"
            where s.Code != "BadCode5"
            orderby s.Name
            select s).ToList<Keys>();

how would I trim it down to one line and have it read from the "blocklist" ? so more like...

var keys = (from s in context.Keys
            where s.Code != ANY OF THE VALUES FROM "BLOCKLIST"
            orderby s.Name
            select s).ToList<Keys>();

8 Answers 8

27

Add it to an array and then use Contains:

var badCodes = new[] { "BadCode1", "BadCode2", "BadCode3", "BadCode4", "BadCode5"};

var keys = (from s in context.Keys
            where !badCodes.Contains(s.Code)
            orderby s.Name
            select s).ToList<Keys>();
Sign up to request clarification or add additional context in comments.

Comments

23

All other answers are correct, but I'm personally a fan of this:

Assuming that you have a list of strings called blackList containing all strings you want to filter out.

var keys = context.Keys.Where(x => !blackList.Contains(x.Code))
    .OrderBy(x => x.Name)
    .ToList();

I just like the way this makes my code readable and easy to understand. But again, every other answer is correct.

Comments

12
var keys = (from s in context.Keys
    where !blackList.Contains(s.Code)
    orderby s.Name
    select s).ToList(); // do you really need the ToList?

an array or list (could be either)

If you're doing this in memory (linq to objects) then a HashSet would perform better than either an array or a list. If you're doing it in a database then it won't make any difference.

Also, do you really need it to be in a list? If you're going to loop through the results or otherwise do something for which IEnumerable<> or IQueryable<> will serve on its own, you're probably better leaving it out.

Comments

7

Create a List<string> with all invalid values

List<string> sBlackList = new List<string>(){"BadCode1", "BadCode2", "BadCode3"};

and replace

where s.Code != ANY OF THE VALUES FROM "BLACKLIST" 

with

where !sBlackList.Contains(s.Code)

Comments

6

You can also use the Except Method similar to this:

var badCodes = new[] { "BadCode1", "BadCode2", "BadCode3", "BadCode4", "BadCode5"};

var blackList = context.Keys.Where(s => badCodes.Contains(s.Code));
var filteredKeys = context.Keys.Except(blackList);

1 Comment

this requires 2 requests to the database. How about RandomStranger 's approach?
5

For detect intersection of any collections you can use .Contains() method. Its simply:

1) determine you blackList:

var blackList = new List<string> {"BadCode1", 
                                  "BadCode2", 
                                  "BadCode3", 
                                  "BadCode4",
                                  "BadCode5"};

2) filter the request by the intersection with the blackList (!blackList.Contains(s.Code)):

var keys = (from s in context.Keys
            where !blackList.Contains(s.Code)
            orderby s.Name
            select s).ToList<Keys>();

Comments

1

You could have a list of codes of black list and check if it does not contain relevant codes

var keys = (from s in context.Keys
            where !blackList.Contains(s.Code)
            orderby s.Name
            select s).ToList<Keys>();

Comments

-1

Try to put all badcodes in a Hashset, and look for values not in "blacklist-hashest"

there is a good example here: https://stackoverflow.com/a/3944821/1117305

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.