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 })

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.


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 }
                  new { b.commonProperty1, commonProperty2 = b.someOtherProp }
              select new { f, b };


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