假设我想解析sql语句
SELECT foo, bar, baz FROM myTable WHERE baz = 2 ORDER BY baz ASC, bar DESC
并以编程方式确定其排序的列和方向。经过一些谷歌搜索,这是我提出的:
List<ParseError> Errors;
TSql100Parser parser = new TSql100Parser(true);
TSqlFragment result = parser.Parse(
new StringReader("SELECT foo, bar, baz FROM myTable WHERE baz = 2 ORDER BY baz ASC, bar DESC"),
out Errors);
foreach (var ts in (result as TSqlScript).Batches)
{
foreach (var st in ts.Statements)
{
SelectStatement selectStatement = (SelectStatement) st;
IList<ExpressionWithSortOrder> _list = selectStatement.QueryExpression.OrderByClause.OrderByElements;
var c0 = _list[0].Expression as ColumnReferenceExpression;
var c1 = _list[1].Expression as ColumnReferenceExpression;
Assert.AreEqual("baz", c0.MultiPartIdentifier.Identifiers[0].Value);
Assert.AreEqual("Ascending", _list[0].SortOrder.ToString());
Assert.AreEqual("bar", c1.MultiPartIdentifier.Identifiers[0].Value);
Assert.AreEqual("Descending", _list[1].SortOrder.ToString());
}
}
此代码工作正常,但我觉得很困惑。有两个地方&#34; as&#34;关键字对我来说似乎很奇怪。
第一个是第6行.TsqlScript是TSqlFragment的子类,所以我想我很幸运能够将它转换为子类。但是TSqlFragment,它是第3行的Parse方法的返回类型,没有任何有用的属性,只有它的子类具有有用的属性。那么什么样的API会暴露一个只有在你碰巧知道把它投射到其他东西时才有用的类呢?
第二个,更令人困惑的使用&#34; as&#34;,用于内部foreach。我怎么可能将ExpressionWithSortOrders变成ColumnReferenceExpressions?它们是类,而不是接口,它们不会相互继承。据我所知,他们既没有明确也没有隐含的相互转换。
更一般地说,如何学会使用这样的API?我在官方的scriptdom文档中找不到关于这个演员的任何信息。 Visual Studio并没有告诉我我可以将这些类互相转换。
答案 0 :(得分:1)
关于“第一案”:
MSDN声明您使用的Parse
方法的重载
使用提供的内容返回脚本片段和错误列表 值。 (继承自TSqlParser。)
所以我想这应该足以知道它是TSqlScript
类; - )
关于“第二案”:
var c0 = _list[0].Expression as ColumnReferenceExpression;
var c1 = _list[1].Expression as ColumnReferenceExpression;
我怎样才能将ExpressionWithSortOrders转换为 ColumnReferenceExpressions?
但你没有。您已将Expression
类的ExpressionWithSortOrder
属性转换为ColumnReferenceExpression
,根据docs完全正常,因为Expression
的类型为ScalarExpression
},ColumnReferenceExpression
继承自那。