Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Same LINQ query using joins but different conditions

Tags:

c#

linq

I have some very similar LINQ queries:

var city = "Hamburg";

var query1 = 
    from c in DB.Customers
    join address in DB.Addresses on c.ID equals address.CustomerID
    where address.City == city
    select c;

var query2 = 
    from c in DB.Customers
    join address in DB.Addresses on c.ID equals address.CustomerID
    where address.City.StartsWith(city)
    select c;

etc.

I want to use a loop to create the queries to reduce redundancy:

var city = "Hamburg";

var expressions = new Expression<Func<string, bool>>[] {
    a => a == city,
    a => a.StartsWith(city)
};

for(int i = 1; i <= 2; i++) {
    queries.Add(
        from c in DB.Customers
        join address in DB.Addresses on c.ID equals address.CustomerID
        where expressions[i](address.City) 
        select c
        );
}

But I don't know how to create the expression array now. Any idea?

like image 312
Dennis Avatar asked Feb 17 '23 22:02

Dennis


2 Answers

var city = "Hamburg";

// predicate should accept Address
var expressions = new Expression<Func<Address, bool>>[] {
    a => a.City == city,
    a => a.City.StartsWith(city)
};

foreach(var predicate in expressions) {
    queries.Add(
        DB.Customers.Join(
           DB.Addresses.Where(predicate), // filtering here
           c => c.ID, 
           a => a.CustomerID, 
           (c, a) => c) // return customer
    ));
}
like image 85
Sergey Berezovskiy Avatar answered Feb 20 '23 11:02

Sergey Berezovskiy


You can use the Join method directly instead of using the query syntax:

public IQueryable<Customer> FindCustomers(Expression<Func<Customer, Address, bool>> predicate)
{
    return DB.Customers.Join(DB.Addresses, c => c.ID, a => d.CustomerID, (c, a) => new { Address = a, Customer = c})
        .Where(pair => predicate(pair.Address))
        .Select(pair => pair.Customer)
}

or you could pass both the Customer and Address:

public IQueryable<Customer> FindCustomers(Expression<Func<Customer, Address, bool>> predicate)
{
    return DB.Customers.Join(DB.Addresses, c => c.ID, a => d.CustomerID, (c, a) => new { Address = a, Customer = c})
        .Where(pair => predicate(pair.Customer, pair.Address))
        .Select(pair => pair.Customer)
}

then you can create your array as:

IQueryable<Customer>[] queries = expressions.Select(expr => FindCustomers(expr)).ToArray();
like image 43
Lee Avatar answered Feb 20 '23 10:02

Lee