我必须使用一个相当特殊的数据源(实际上是会计应用程序的接口)。虽然它非常强大,但我必须跳过很多圈才能从中获取我想要的数据。例如,如果我想获取一个表的内容并指定它应该返回哪些列,我必须遍历 .Columns 集合并将 .SetVisible() 调用到我想要的那些。
目前我们有一个方法可以包装这个并允许我们以更简单的方式指定事物,但是该函数的参数列表正在快速增长,并且大多数时候我们只需要在调用它时指定其中的几个. 简而言之 - 这是一个不灵活的解决方案。
我想到的第一个解决方案是这样的:
DataTable result = DataSourceWrapper.StartQuery("TableName")
.SetVisibleColumns("Col1", "Col2", "Col3")
.SetCriteria("CriteriaName", "Param1Name", CriteriaParam1, "Param2Name", CriteriaParam2)
.SetFilter("Col4 = ? AND Col5 = ?", FilterParam1, FilterParam2)
.SetReportParams("Param1Name", ReportParam1, "Param2Name", ReportParam2)
.Execute();
Criteria、Filters 和 ReportParams 是特定于应用程序的一些东西,我不会在这里讨论它们。但总体思路是这样的。它实际上类似于调用方法,除了您可以选择要指定的参数(通过调用特定方法)并获得更多 IntelliSense 帮助。您还可以使用方法调用的顺序。
请注意,SetFilter()
有一个要解析的表达式。这是 DataSource 造成困难的另一件事 - 它可以很好地处理表达式,但是您必须将它们作为特殊对象树传递,这又是相当冗长的编写。在上一个问题中,我寻求有关解析此类表达式的帮助。当前的 wrapper-method 有一个自制的表达式解析器,它可以解析简单的表达式,但我想使对它们的支持更完整。
在那个问题中,提出了Irony项目。看完之后,我认为它确实适合这种需求。但过了一会儿,我突然意识到,它比那更强大。为什么不让我自己的查询语言完全适合这个任务呢?上面的内容看起来像:
DataTable result = DataSourceWrapper.Query(@"
SELECT Col1, Col2, Col3
FROM TableName
WITH CRITERIA CriteriaName(Param1Name={0}, Param2Name={1})
WITH REPORTPARAMS (Param1Name={2}, Param2Name={3}
WHERE Col4 = {4} AND Col5 = {5}",
CriteriaParam1, CriteriaParam2,
ReportParam1, ReportParam2,
FilterParam1, FilterParam2
);
但是……这不是矫枉过正吗?两种方法的优缺点是什么?我看到的是:
专业 DSL:
- 查询更简洁;
专业方法:
- 更多智能感知支持;
- 方法名称/参数名称(和注释)减少了对文档的需求(必须彻底记录 DSL);
- 可能会更快创建?我从来没有创建过自己的 DSL,所以我不知道有多少工作量。讽刺似乎从我肩上卸下了很多担子,但还剩下多少呢?
补充:为了澄清,这两种方法都只能由编码人员使用。外部人员和业务分析师不会使用它。