score:11

Accepted answer

Assuming the shared properties implement equality etc properly, you might want to do something like:

// In an extensions class somewhere. This should really be in the standard lib.
// We need it for the sake of type inference.
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items)
{
    return new HashSet<T>(items);
}

var shared = foos.Select(foo => new { foo.SharedProperty1, foo.SharedProperty2 })
                 .ToHashSet();

var query = bars.Where(bar => shared.Contains(new { bar.SharedProperty1,
                                                    bar.SharedProperty2 }));

The other options using joins will certainly work - but I find this clearer for the expressing the idea that you only want to look at each bar entry once, even if there are several foo items with that property.

score:3

Sounds like you need a join:

var fooList = new List<foo>();
var barList = new List<bar>();

// fill the lists

var results = from f in fooList
              join b in barList on 
                  new { f.commonPropery1, f.commonProperty2 }
                  equals 
                  new { b.commonProperty1, commonProperty2 = b.someOtherProp }
              select new { f, b };

score:1

Any should work if it's irrelevant how many foo's match:

var selectedBars = bars.Where(bar => 
                                foos.Any(foo => foo.Property1 == bar.Property1 
                                             && foo.Property2 == bar.Property2));

If all foos should match use All

var selectedBars = bars.Where(bar => 
                                foos.All(foo => foo.Property1 == bar.Property1 
                                             && foo.Property2 == bar.Property2));

If the list of foos is large use a HashSet as pointed out in John Skeets answer.


Related Articles