表达式树串行 [英] Expression Tree Serializer

查看:104
本文介绍了表达式树串行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用LINQ表达式在客户端,它们序列化和执行他们在服务器端

I want to use Linq Expressions on Client Side, Serialize them and Execute them on server Side.

有关这一点,我想用:的 http://expressiontree.codeplex.com/

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

但我想执行。他们agains一个自己的WCF呼叫

But I want to Execute them agains a own WCF Call.

这意味着我有WCF方呼叫:

That means i Have a Call on WCf Side:

ImageDTO[] GetImages(XElement exp);



我现在要对客户端上的IQueryable(关于这一点我可以执行LINQ表达式),以及我有一个Serverside集团IQueryable的(从我的数据接取层,上至极我要执行的序列化的表达)。

I now want to have a IQueryable on Client Side (on which I can execute Linq Expressions), and I have a IQueryable on Serverside (from my data acess layer, on wich i want to execute the serialized expression).

但我不知道如何做到这一点,我没有找到任何的例子...

But I'm not sure how to do this, and I don't find any Examples...

在客户端,我想我应该在Class实现查询,这个类我告诉在构造函数中使用我的实现QueryProvider的(从我所说的WCF服务)。但我不知道这是正确的...

On Client Side i think I should implement Query in a Class, this class I tell 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 a Example.

推荐答案

还有的的IQueryable℃的实施; T> 在框架 - 的 MSDN:EnumerableQuery< T>

There's an implementation of IQueryable<T> in the framework - MSDN: EnumerableQuery<T>

如果您可以使用此客户端上,以构建查询,你可以从整个表达式树的的IQueryable< T> .Expression 属性

If you can use this on the client to build the query, you can get the whole Expression Tree from the IQueryable<T>.Expression property.

您必须对此进行测试,看它是否与表达式树串行工作的。

You'll have to test this to see if it works with that Expression Tree Serializer.

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

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

var expressionTree = query.Expression;

您可以再序列化的表达,喷射它进行的跨线,然后反序列化。

You can then serialize the expression, squirt it accross the wire and then deserialize it.

那么问题是,表达式树是基于 EnumerableQuery< T>

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

所以,你需要更换,以你的的IQueryable< T>从你的真正的<$ C $ 源C>的DbContext

So you need to replace that with your IQueryable<T> source from your real DbContext

这得到了的的凌乱,但我已经写了使用<$ C实现$ C> ExpressionVisitor:

This gets a bit messy, but I've written an implementation using an 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 );
    }
}



调用这是直截了当:

Calling this is straight forward:

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

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

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

这篇关于表达式树串行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆