Search code examples
c#.netlinq-to-sqlrefactoring

How to refactor multiple similar Linq-To-Sql queries?


Suppose I have the two following Linq-To-SQL queries I want to refactor:

var someValue1 = 0;
var someValue2= 0;
var query1 = db.TableAs.Where( a => a.TableBs.Count() > someValue1 )
              .Take( 10 );
var query2 = db.TableAs.Where( a => a.TableBs.First().item1 == someValue2)
              .Take( 10 );

Note that only the Where parameter changes. There is any way to put the query inside a method and pass the Where parameter as an argument?

All the solutions posted in the previous question have been tried and failed in runtime when I try to enumerate the result.

The exception thrown was: "Unsupported overload used for query operator 'Where'"


Solution

  • Absolutely. You'd write:

    public IQueryable<A> First10(Expression<Func<A,bool>> predicate)
    {
        return db.TableAs.Where(predicate).Take(10);
    }
    

    (That's assuming that TableA is IQueryable<A>.)

    Call it with:

    var someValue1 = 0;
    var someValue2= 0;
    var query1 = First10(a => a.TableBs.Count() > someValue1);
    var query2 = First10(a => a.TableBs.First().item1 == someValue2);
    

    I believe that will work...

    The difference between this and the answers to your previous question is basically that this method takes Expression<Func<T,bool>> instead of just Func<T,bool> so it ends up using Queryable.Where instead of Enumerable.Where.