The same LINQ query using joins, but with different conditions

I have 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 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 do not know how to create an array of expressions. Any idea?

+4
source share
4 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 )); } 
+3
source

You can use the Join method directly, rather than 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 can pass both 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(); 
+3
source

You can save the common part of the connection in the general request.

 var query = from c in DB.Customers join address from DB.Addresses on c.ID equals address.CustomerID select new {A=a, C=c}; var query1 = query.Where ( item => item.A.temp == item.C.test).Select (item => item.C); var query2 = query.Where ( item => item.A.temp2 == item.C.test2).Select (item => item.C); 
+1
source
 var queries=( from f in new Func<Address, bool>[] { x => x.City==city, x => x.City.StartsWith(city) } select from c in DB.Customers join address in DB.Addresses on c.ID equals address.CustomerID where f(address) select c ).ToArray(); 
  • You create an expression array , so you still get an expression array ; you do not need to make the delegates an expression array .

  • You don't need foreach

  • If you add additional expressions to queries later, change ToArray() to ToList()

  • If you want to change Func<Address, bool> before creating queries , then define a local variable for it and simply replace Func<Address, bool>[]

+1
source

All Articles