Search code examples
c#linqjoinanti-join

Does C# linq support "anti join" semantics?


I've googled a little while and didn't find a direct anti-join semantics example. How to do this in C# LINQ as an example?


Solution

  • An anti-join as basically a set of data that is not conained in another set, can be represented in Linq with a an IEnumerable.Except like this:

    double[] numbers1 = { 2.0, 2.0, 2.1, 2.2, 2.3, 2.3, 2.4, 2.5 };
    double[] numbers2 = { 2.2 };
    
    IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);
    
    foreach (double number in onlyInFirstSet)
        Console.WriteLine(number);
    

    This of course requires the definition of an IEqualityComparer for custom classes.

    An alternative syntax using where would be:

    var antiJoin = numbers1.Where(number => !numbers2.Contains(number));
    

    Read more on Enumerable.Except Method on Microsoft docs.

    Edit:

    As for "db driven linq" here is an example that will work for Entity Framework using Except:

    
    var filteredProducts = db.Products.ToList()
        .Except(db.Orders.Where(o => o.OrderId = 123)
            .Select(o => o.Product).ToList())
        .ToList();
    

    as for the where alternative:

    var filterProducts = db.Orders.Where(o => o.OrderId = 123)
        .Select(o => o.Product).ToList();
    var antiJoinProducts = db.Products.Where(p => !filterProducts.Contains(p));