Though the answers above are correct, they are "give a man a fish" answers. It would be better to take this opportunity to learn how to break down a problem into small pieces, and then reassemble the results into queries.
In the above, what I need/want to do
is include the SavedOption only if the
call to OptionTextDoesMatch AND SomeID
of the savedOption is found in the
list of SomeID in itemOptions.
Let me try to rephrase this someone confusing sentence.
You have a list of SavedOptions. Each SavedOption has an ID and some text.
You have a list of Options. Each Option has an ID and some text.
You wish to filter the list of SavedOptions in order to get the SavedOptions which match some Option on BOTH text and ID.
Break the problem down. Suppose you did not have a sequence of SavedOptions. Suppose you just had one SavedOption, and a list of Options. How would you tell if it was a match?
That's straightforward:
SavedOption mySavedOption = whatever;
bool matchExists = itemOptions.Any(item=>
OptionTextDoesMatch(item, mySavedOption) &&
item.SomeID == mySavedOption.SomeID);
Does that make sense?
Now suppose you wanted to make a predicate out of that which takes a SavedOption. How would you do it? That's straightforward:
Func<SavedOption, bool> predicate = savedOption =>
itemOptions.Any(item=>
OptionTextDoesMatch(item, savedOption ) &&
item.SomeID == savedOption.SomeID);
This is a predicate which determines whether a single item matches.
Still making sense? Stop me if something seems confusing.
So to make a filter out of it, apply the predicate to every item on the list of saved options:
result = savedOptions.Where(savedOption =>
itemOptions.Any(item=>
OptionTextDoesMatch(item, savedOption) &&
item.SomeID == savedOption.SomeID));
Or, in query comprehension form, which I personally find easier to read.
result = from savedOption in savedOptions
where itemOptions.Any(item =>
OptionTextDoesMatch(item, savedOption) &&
item.SomeID == savedOption.SomeID)
select savedOption;
But a possibly better choice is to use a join. A join is simply an optimization of a filter on the Cartesian product of two collections that are related by an id.
result = from savedOption in savedOptions
join itemOption in itemOptions
on savedOption.SomeID equals itemOption.SomeID
where OptionTextDoesMatch(itemOption, savedOption)
select savedOption;
Is that clear?