views:

49

answers:

1

I'm trying to use the specification pattern implemented as a Linq expression so that Linq providers can parse it to produce efficient database queries.

This gives the basic idea.

I am having a hard time trying trying to get it working with a parent/child query

class Parent
{
    public int Foo;

    public IList<Child> Children = new List<Child>();
}

class Child
{
    public int Bar;
}

class Program
{
    static void Main(string[] args)
    {
        IQueryable<Parent> qry = GetQry(); //initialised


        //This works but duplicates the IsBigBar() logic
        //Included to show what I am trying to query on
        var parentsWithBigChildBars =
                from parents in qry
                where parents.Children.Any(child => child.Bar > 10) 
                select parents;

        var parentsWithBigChildBars2 =
               from parents in qry
               where parents.Children.Any( ?? ) //but how do i access my IsBigBar() expression from here?
               select parents;
    }


    //I want to re-use it to pull parents back!
    public Expression<Func<Child, bool>> IsBigBar()
    {
        return child => child.Bar > 10;
    }

    //I'f i use this as the Any() delegate, it compiles & runs but not an expression so evaluated client side
    public Func<Child, bool> IsBigBar2()
    {
        return child => child.Bar > 10;
    }
}
A: 

You want:

    var predicate = IsBigBar();
    var parentsWithBigChildBars2 =
           from parents in qry
           where parents.Children.Any(predicate) 
           select parents;

The extra var is very important. It prevents the query provider (that owns qry) from trying to interpret IsBigBar() and instead points it at the result of that method.

Craig Stuntz
hm, I get Unable to cast object of type 'System.Linq.Expressions.ConstantExpression' to type 'System.Linq.Expressions.LambdaExpression'. Is that a bug in my provider?
Noel Kennedy
Is the code in your question the *actual* code you are running?
Craig Stuntz