Reputation: 97
I have a list of TelephoneDataType objects
public List<TelephoneDataType> Values { get; set; }
The TelephoneDataType object has a enum property called ChartType
public class TelephoneDataType
{
public ChartType ChartId { get; set; }
}
So from this Values List, I want to pull out all TelephoneDataType objects that has ChartId set to any of the following values:
Answered Abandoned ExpectedWait InQueue
Here is my failed attempt
var items = telephoneData.Values
.Where(c => c.ChartId == Enums.ChartType.Answered)
.Where(c => c.ChartId == Enums.ChartType.Abandoned)
.Where(c => c.ChartId == Enums.ChartType.ExpectedWait)
.Where(c => c.ChartId == Enums.ChartType.InQueue).ToArray();
Upvotes: 1
Views: 79
Reputation: 36
I guess that the best way, which will help you not only in this situation - to write a special extension method for enums:
public static class EnumExtensions
{
public static bool InSet<T>(this T target, params T[] possibleValues) where T : struct
{
return possibleValues.Contains(target);
}
}
And solution is:
var items = telephoneData.Values
.Where(c => c.ChartId.InSet(Enums.ChartType.Answered,
Enums.ChartType.Abandoned,
etc...);
Upvotes: 0
Reputation: 97
Each Where
returns a filtered enumerable, so after your first Where
you are only left with a single ChartType
. You must combine the conditions into a single Where
operation like this:
var items = (telephoneData.Values
.Where(c => c.ChartId == Enums.ChartType.Answered || c.ChartId == Enums.ChartType.Abandoned || c.ChartId == Enums.ChartType.ExpectedWait || c.ChartId == Enums.ChartType.InQueue)
.ToArray());
Upvotes: 0
Reputation: 186803
I'd rather implement an extension method for Enums.ChartType
e.g.
public static class EnumsChartTypeExtensions {
//TODO: find out a proper name for the method
public static Boolean IsOnLine(this Enums.ChartType value) {
return value == Enums.ChartType.Answered ||
value == Enums.ChartType.Abandoned ||
value == Enums.ChartType.ExpectedWait ||
value == Enums.ChartType.InQueue;
}
}
And so your Linq will be far more readable:
var items = telephoneData.Values
.Where(c => c.ChartId.IsOnLine())
.ToArray();
Yet another advantage of the solution is if you add some statuses into Enums.ChartType
(e.g. WaitingForAnswer
) all you'll have to do is to update the extension methods only (and not all your Linq within the whole application)
Upvotes: 1
Reputation: 8276
Your current solution is doing &&
's between your .Where
clauses. You need to make them ||
's by doing one of the following
var items = telephoneData.Values
.Where(c => c.ChartId == Enums.ChartType.Answered
|| c.ChartId == Enums.ChartType.Abandoned
|| c.ChartId == Enums.ChartType.ExpectedWait
|| c.ChartId == Enums.ChartType.InQueue
)
.ToArray();
or (which is more readable and easier to update/maintain)
var myFilterList = new []
{
Enums.ChartType.Answered,
Enums.ChartType.Abandoned,
Enums.ChartType.ExpectedWait,
Enums.ChartType.InQueue
};
var items = telephoneData.Values
.Where(c => myFilterList.Contains(c.ChartId)
.ToArray();
Also remember that your .Where
clauses aren't executed immediately.
They are only executed when you do a .ToList
, .ToArray
, etc.
You can read more about that here: https://msdn.microsoft.com/en-us/library/vstudio/bb738633(v=vs.100).aspx
Upvotes: 3
Reputation: 6738
Think through your query step by step. First you get all charts with ID Answered
. You then take that list and filter it for Abandoned
, but the entries are all Answered
already.
Try using the or operator.
var items = telephoneData.Values
.Where(c => c.ChartId == Enums.ChartType.Answered ||
c.ChartId == Enums.ChartType.Abandoned ||
c.ChartId == Enums.ChartType.ExpectedWait ||
c.ChartId == Enums.ChartType.InQueue).ToArray();
Upvotes: 0