【问题标题】:Intercept the 'Expression' property of IQueryable Provider and gets its e-sql拦截 IQueryable Provider 的 'Expression' 属性并获取其 e-sql
【发布时间】:2011-09-22 21:17:33
【问题描述】:

通常我可以使用 linq 以典型方式查询实体上下文,

IQueryable<Product> query = from p in db.Products
                            where p.ProductID > 1
                            select query;

现在假设我想获取这个 IQueryable 的表达式,对其进行序列化,然后将其通过网络传递到另一端进行重构,

Expression ex = query.Expression;

XElement xExpression = serializer.Serialize(ex); 

wcfClient.InvokeSomeServiceMethod(xExpression);

我将如何在另一端重建它? (具体是服务器端)

我需要创建一个新的 IQueryable 实例,并通过实际传入一个 Expression 实例来“设置”底层提供程序使用的表达式,这可能吗?当然,默认情况下 IQueryable 上没有设置器。更具体地说,我只需要一个 ObjectQuery,这样我就可以调用 ToTraceString() 并在另一端获取实体 sql。我似乎找不到任何可以直接注入表达式的点。

谢谢。

【问题讨论】:

  • 您的问题是:如何在服务器内部传递和调用查询?
  • 是的,基本上。不过我需要传入一个 Expression 实例,因为查询是在客户端而不是服务器上编写的。
  • 这并不容易。看看 OData 是如何做到这一点的(通过线路传递查询并在服务器端重建它)

标签: c# wcf linq entity-framework-4 xml-serialization


【解决方案1】:

我建议你看看InterLINQ。它提供了序列化表达式并通过 WCF 传输的能力。

我将它与 NHibernate 一起使用,以实现与您所描述的结果相似的结果,并且它似乎运行良好。 (不过有一点需要注意,正如其他人所建议的那样,WCF 数据服务/OData 会更快/更容易)。

【讨论】:

    【解决方案2】:

    真的,你有两个选择。

    1. 不要通过网络传递一般查询。服务器应该有一个客户端调用的GetProductsWithProductIdGreaterThan 方法。

    2. WCF Data Services

    第三个选项,即您要求的选项,很难。= 即使您非常精通 LINQ、WCF 和 Expression,它仍然非常困难。

    【讨论】:

    • 我认为第一个选项是最简单的,但它不像其他选项那样动态
    • +1 带有 OData 的 WCF 数据服务正是针对这种情况,否则您将编写自己的 IQueryable provider 来处理服务器端和客户端 - 顺便说一句。表达式树是不可序列化的,因此您还必须进行自己的序列化过程以将它们从服务器传递到客户端。
    猜你喜欢
    • 2014-04-26
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 2016-12-03
    • 1970-01-01
    相关资源
    最近更新 更多