0

我在企业环境中工作,我们的前端(客户端和 Web)没有直接的数据库访问权限,而是通过网络与服务通信。针对外部可用的 ASP.Net Web API 的概念验证工作已经开始,我们正在考虑尝试使用 IQueryable 的实现来使用 OData。问题是 Web API 将是另一个“前端”,它访问一个网络跳远的服务层,这意味着我们必须编写自己的 IQueryable 实现。

一个 IQueryable 实现是我所说的 RangeQueryable,它是抽象的并采用三个通用参数;TRaw,TData,TRange。这将是一个IQueryable<TData>

var queryable = new RangeQueryableImplementation<RawData, ConvertedData, DateTime>("Created");

在前面的代码行中,RawData 是 TRaw,ConvertedData 是 TData,DateTime 是 TRange。

RangeQueryable 也有两个抽象方法。

public abstract IEnumerable<TRaw> GetData(TRange from, TRange to);
public abstract TData Convert(TRaw raw);

GetData 将通过网络调用服务层,并在调用中使用fromto作为参数。然后 Convert 会将数据转换为我的类型。

TRaw 是服务将返回的类型,TData 是前端内的类型和 IQueryable 内的类型,TRangei 是范围类型。

所以这是可能的:

queryable.Where(d => d.Created < DateTime.Now && d.Created > DateTime.Now.AddDays(-5))

...或等效的 OData。

这就是 ExpressionVisitor 的用武之地。我需要使用 ExpressionVisitor 来查找 From 和 To 日期。

我看过一些教程并提出了一些想法。我遇到的问题是我不知道如何对 ExpressionVisitor 进行单元测试。我将如何创建一个等效于 Queryable 扩展方法创建的表达式?

4

1 回答 1

1

我会将每个测试用例编写为具有某个表达式树作为输入,并且(在您的情况下)期望某个范围作为输出。可以通过多种方式指定表达式树: - 您可以通过调用 Expression.Call 等手动创建表达式树(每种类型的表达式节点都有一个创建它的表达式类型的静态方法)。- 您可以像上面一样使用扩展方法创建表达式树 - 您可以使用查询理解来创建表达式树(select from where 语法)

这些中的每一个最终都会有一个表达式树。扩展方法最终调用表达式。方法也是。它们中的大多数实际上只是将一个 Call 表达式注入到树中给自己——您可以查看反汇编程序或调试器中的公开可用源代码。

查询理解语法只是编写对扩展方法的调用的另一种方式,因此您最终也会得到相同的结果。

在单元测试中,您甚至不必运行可查询对象,因此只需创建它、对其应用表达式树并运行表达式访问者就足够了。

于 2012-09-11T08:57:02.587 回答