Expression Tree Serializer

I want to use client-side Linq expressions, serialize them and execute them on the server side.

For this I want to use: http://expressiontree.codeplex.com/

But I want to execute them again using my own WCF call.

This means that I have a call on the WCf side:

ImageDTO[] GetImages(XElement exp);

Now I want to have IQueryable on the client side (on which I can execute Linq expressions), and I have IQueryable on Serverside (from my data access level in which I want to execute a serialized expression).

But I'm not sure how to do this, and I have not found examples ...

On the client side, I think I should implement Query in the class, this class I say in the constructor to use my implementation of QueryProvider (from where I call the WCF service). But I'm not sure if this is correct ...

Maybe someone can help with an example.

+5
source share
2 answers

In the implementation there is IQueryable<T>-MSDN: EnumerableQuery<T>

If you can use this on the client to create a query, you can get the entire expression tree from the property IQueryable<T>.Expression.

You will need to check this to see if it works with this expression tree serializer.

var iQueryable = new EnumerableQuery<Model>( Enumerable.Empty<Model>() );

var query = iQueryable.Include( ... ).Where( ... ).OrderBy( ... );

var expressionTree = query.Expression;

Then you can serialize the expression, direct it to the wire and then deserialize it.


Then the problem is that the expression tree is based on EnumerableQuery<T>.

, IQueryable<T> DbContext

, ExpressionVisitor:

IQueryable FixupExpressionTree( ObjectContext ctx, Type entityType, Expression expression )
{
    var tObjectContext = ctx.GetType();
    var mCreateObjectSetOpen = tObjectContext.GetMethod( "CreateObjectSet", new Type[ 0 ] );
    var mCreateObjectSetClosed = mCreateObjectSetOpen.MakeGenericMethod( entityType );

    var objectQuery = ( ObjectQuery ) mCreateObjectSetClosed.Invoke( ctx, null );

    var eFixed = new Visitor( objectQuery, entityType ).Visit( expression );

    var qFixed = ( ( IQueryable ) objectQuery ).Provider.CreateQuery( eFixed );

    return qFixed;
}

ExpressionVisitor:

public class Visitor : ExpressionVisitor
{
    ObjectQuery _Source = null;
    Type _EntityType = null;

    public Visitor( ObjectQuery source, Type entityType ) { _Source = source; _EntityType = entityType; }

    protected override Expression VisitConstant( ConstantExpression node )
    {
        if ( !node.Type.Name.Contains( "EnumerableQuery" ) ) return base.VisitConstant( node );

        var eConstantInstance = Expression.Constant( _Source );
        var eConstantArgument = Expression.Constant( MergeOption.AppendOnly );

        var tObjectQueryOpen = typeof( ObjectQuery<> );
        var tObjectQueryClosed = tObjectQueryOpen.MakeGenericType( _EntityType );
        var eMergeAsMethod = tObjectQueryClosed.GetMethod( "MergeAs", BindingFlags.Instance | BindingFlags.NonPublic );

        return Expression.Call( eConstantInstance, eMergeAsMethod, eConstantArgument );
    }
}

:

Type entityType = ...
Expression expression = ...
DbContext db = ...

ObjectContext ctx = ( ( IObjectContextAdapter ) db ).ObjectContext;

IQueryable query = FixupExpressionTree( ctx, entityType, expression );
+2

, Interlinq, , , Silverlight.

https://github.com/jogibear9988/Interlinq-2

+1

All Articles