我的 WCF 数据服务的存储库模式实现存在问题。总而言之,我试图在客户端应用程序中使用存储库模式,该模式将可插入模型用于所需的存储库。根本问题是我的存储库接口 IRepository 只能知道它存储的项目的接口类型变体。这是为了将客户端应用程序从订单的数据服务实现中抽象出来,例如
IRepository<IOrder> : IQueryable<T>
通常,在涉及数据服务之前,此概念可以正常工作。我目前正在使用 NuGet 的 Data Services v5.4。如果我在我的存储库上执行像 ToList() 这样简单的操作,一切正常,翻译会将结果转换为来自 OData 服务的订单列表。但是,如果我尝试执行 orderby,查询表达式会变得更加复杂,并且无法填充返回类型,因为它尝试创建可查询类型的接口变体的实例。即尝试创建 IOrder 的实例而不是 Order。
repository.OrderBy(order => order.Id).ToList(); // Fails
但是,在客户端级别,如果我使用 Cast 强制类型,那么它可以工作......
repository.Cast<Order>(order => order.Id).ToList(); // Suceeds
显然,这违背了断开连接类型的口头禅,因为我的客户端应用程序必须知道数据服务库中的强类型“订单”,如果我想在将来切换出 OData,我想避免这种情况。
接下来,我偶然发现了 Data Service Client 端 Context 类,它允许您处理解析类型的方法,但在我的情况下,由于某种原因从未调用过解析。
我随后开始查看的是 ExpressionVisitors,我仍然相信它是我摆脱这种混乱的门票,它必须能够将任何 IOrder 参数转换为我的存储库中的 Order 参数,以便查询返回强类型但继续接口类型。
当使用空壳 ExpressionVisitor 实现时,例如
MyVisitor : ExpressionVisitor
这对于非数据服务查询(例如,可查询的列表之类的东西)很好用,但对于数据服务存储库模式查询,您会收到无用的(至少对我而言)消息“必须是可简化节点”。我猜是表达式树访问者遇到了数据服务查询自定义的节点类型并且不知道如何处理它。但是我认为 ExpressionVisitor 会简单地复制树中的内容,除非被告知做不同的事情?
无论如何,我要问的是,如何通过将此 ExpressionVisitor 与 OData 查询一起使用来替换查询的返回类型?我试图寻找某种现有的数据服务表达式访问者,但找不到。我希望我的客户端数据服务从接口类型查询生成查询,但返回同名的强类型。