Advertisement
Advertisement


Linq select objects in list where exists IN (A,B,C)


Question

I have a list of orders.
I want to select orders based on a set of order statuses.

So essentially select orders where order.StatusCode in ("A", "B", "C")

// Filter the orders based on the order status
var filteredOrders = from order in orders.Order
                     where order.StatusCode.????????("A", "B", "C")
                     select order;
2019/02/03
1
173
2/3/2019 5:17:15 PM

Accepted Answer

Your status-codes are also a collection, so use Contains:

var allowedStatus = new[]{ "A", "B", "C" };
var filteredOrders = orders.Order.Where(o => allowedStatus.Contains(o.StatusCode));

or in query syntax:

var filteredOrders = from order in orders.Order
                     where allowedStatus.Contains(order.StatusCode)
                     select order;
2013/01/10
293
1/10/2013 12:20:02 PM

var statuses = new[] { "A", "B", "C" };

var filteredOrders = from order in orders.Order
                             where statuses.Contains(order.StatusCode)
                             select order;
2013/01/10

NB: this is LINQ to objects, I am not 100% sure if it work in LINQ to entities, and have no time to check it right now. In fact it isn't too difficult to translate it to x in [A, B, C] but you have to check for yourself.

So, instead of Contains as a replacement of the ???? in your code you can use Any which is more LINQ-uish:

// Filter the orders based on the order status
var filteredOrders = from order in orders.Order
                     where new[] { "A", "B", "C" }.Any(s => s == order.StatusCode)
                     select order;

It's the opposite to what you know from SQL this is why it is not so obvious.

Of course, if you prefer fluent syntax here it is:

var filteredOrders = orders.Order.Where(order => new[] {"A", "B", "C"}.Any(s => s == order.StatusCode));

Here we again see one of the LINQ surprises (like Joda-speech which puts select at the end). However it is quite logical in this sense that it checks if at least one of the items (that is any) in a list (set, collection) matches a single value.

2015/07/26

Try with Contains function;

Determines whether a sequence contains a specified element.

var allowedStatus = new[]{ "A", "B", "C" };
var filteredOrders = orders.Order.Where(o => allowedStatus.Contains(o.StatusCode));
2013/01/10

Just be careful, .Contains() will match any substring including the string that you do not expect. For eg. new[] { "A", "B", "AA" }.Contains("A") will return you both A and AA which you might not want. I have been bitten by it.

.Any() or .Exists() is safer choice

2018/06/19