1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public static Func<TDbTable, bool> GetWhereClauseForAll<TDbTable, TEntity>( this List<TEntity> objects, Func<TEntity, Func<TDbTable, bool>> comparison) { Func<Func<TDbTable, bool>, Func<TDbTable, bool>, Func<TDbTable, bool>> concatWhereClauses = (existingWhereClause, toBeAddedWhereClause) => row => existingWhereClause(row) || toBeAddedWhereClause(row); Func<TDbTable, bool> whereClause = comparison(objects.First()); for (int i = 1; i < objects.Count; i++) whereClause = concatWhereClauses(whereClause, comparison(objects[i])); return whereClause; }
Refactorings
No refactoring yet !
Ants
November 16, 2009, November 16, 2009 08:57, permalink
One of these two is more readable and easier to understand depending on how well your brain can parse things. Although, I posted the compact form first, I actually got to the compact form by iteratively simplifying the verbose form.
Compact
1 2 3 4 5 6
public static Func<TDbTable, bool> GetWhereClauseForAll<TDbTable, TEntity>( this List<TEntity> objects, Func<TEntity, Func<TDbTable, bool>> comparison) { return dbTable => objects.Any(entity => comparison(entity)(dbTable)); }
Verbose
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public static Func<TDbTable, bool> GetWhereClauseForAll<TDbTable, TEntity>( this List<TEntity> objects, Func<TEntity, Func<TDbTable, bool>> comparison) { Func<TDbTable, bool> whereClause = (TDbTable dbTable) => { foreach (TEntity entity in objects) { Func<TDbTable, bool> compare = comparison(entity); if (compare(dbTable)) return true; } return false; }; return whereClause; }
Suddenly found myself having written this piece of ugly Extension method, and I'm wondering if there is a more clear way of doing this.
The idea is that given a list of objects, I want to generate the where expression/func that will give me all rows in the database (TDbTable), and I have a comparison that will match TEntity to TDbTable. In reality it generates this kind of SQL: "WHERE id = 1 or id = 2 or id = 3 ... "