1

I work on project that use some dynamic linq query to an entities. i have huge amount of case and to avoid code duplication i refactoring to a method. But using method which isn't in store expression will result to throw an exception. One of solutions is to encapsulate method result into an expression which can be interpreted by linq to entitie query.

Consider that code :

parentExpression = x => x.child.Any(y=>IsGoodChild(y,childType, childSize));

private bool IsGoodChild(child c, int childType, int childSize){
     return c.type == childType && c.size == childSize;
}

"parentExpression " is predicate of type "Parent" of my EF. This code throw an exception, "IsGoodChild" method return a boolean and can't be interpreted by linq to Entities.

So, i would like something like this :

parentExpression = x => x.child.AsQueryable().Any(IsGoodChild(childType, childSize));

private System.Linq.Expression.Expression<Func<child, bool>> IsGoodChild(int childType, int childSize){
     return  ????
}

So how can i do "IsGoodChild(...)" can work even if which not take x.child attribute ? Thx for advance


Re,

I try something, when i write lambda directly in expression like this :

parentExpression = x => x.child.Any(y=>y.type == childType && y.size == childSize);

i used extract method from resharper and generate it this :

private Expression<Func<child,Boolean>> IsGoodChildFunctional(Int32 childType, Int32 childSize)
{
    return c => c.type == childType && c.size == childSize; 
}

But i also have .NET Framework Data Provider error 1025' error ...

2 Answers 2

0

In this case the compiler is clever, given an anonymous method it will switch between an expression tree or a compiled lambda depending on the declared type. The following should work:

private Expression<Func<child,Boolean>> 
IsGoodChildFunctional(Int32 childType, Int32 childSize)
{
    return c => c.type == childType && c.size == childSize; 
}

which would be used like so:

parentExpression = x => x.child
                         .AsQueryable()
                         .Any(IsGoodChildFunctional(childType,childSize));
2
  • it not work => .NET Framework Data Provider error 1025' error
    – bor1s
    Commented Dec 21, 2012 at 14:59
  • 1
    It should be y => IsGoodChildFunctional(y.childType, y.childSize) otherwise the lambda expression is still seen as a Func and not an expression. See also stackoverflow.com/a/9517994/861716. Commented Dec 21, 2012 at 16:27
0

Create a static generic method which will return an Expression. The Expression is built by using factory methods.

public static Expression<Func<TTargetObject,Boolean>> IsGoodChildFunctional<TTargetObject>(Int32 childType, Int32 childSize)
{
            var e = Expression.Parameter(typeof(TTargetObject), "e");
            var childTypeMember = Expression.MakeMemberAccess(e, typeof(TTargetObject).GetProperty("childType"));
            var childSizeMember = Expression.MakeMemberAccess(e, typeof(TTargetObject).GetProperty("childSize"));
            var  childTypeConstant = Expression.Constant(childType, childType.GetType());
            var  childSizeConstant = Expression.Constant(childSize, childSize.GetType());
            BinaryExpression b;
            BinaryExpression bBis;
            Expression<Func<TTargetObject, bool>> returnedExpression;
            b = Expression.Equal(childTypeMember , childTypeConstant );
            bBis2 = Expression.Equal(childSizeMember, c2);
            var resultExpression = Expression.AndAlso(b, bBis);
            returnedExpression = Expression.Lambda<Func<TTargetObject, bool>>(resultExpression , e);
            return returnedExpression;
}

It is called like this:

var predicat = IsGoodChildFunctional<child>(childType, childSize);
parentExpression = x => x.child.Any(predicat);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.