“as”关键字在TSql100解析器代码中被认为是令人困惑的
本文关键字:认为是 代码 关键字 as TSql100 | 更新日期: 2023-09-27 18:26:08
假设我想解析 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());
}
}
这段代码工作正常,但我发现它非常混乱。有两个地方的"as"关键字对我来说似乎很奇怪。
其中第一个在第 6 行。TsqlScript 是 TSqlFragment 的一个子类,所以我想我很幸运能够将其转换为子类。但是 TSqlFragment(第 3 行 Parse 方法的返回类型(没有任何有用的属性,只有它的子类具有有用的属性。那么,什么样的 API 会公开一个类,而这个类只有在您碰巧知道将其转换为其他内容时才有用?
"as"的第二种更令人困惑的用法用于内部foreach。我怎么可能将 ExpressionWithSortOrders 转换为 ColumnReferenceExpressions?它们是类,而不是接口,并且它们不会相互继承。据我所知,它们既没有明确也没有隐含地相互转换。
更一般地说,如何学习使用这样的 API?我在官方脚本文档中没有找到有关此选角的任何内容。Visual Studio并没有告诉我我可以把这些类变成彼此。
关于"第一种情况":
MSDN 指出您使用的Parse
方法的重载
使用提供的 返回脚本片段和错误列表 值。(继承自 TSqlParser。
所以我想这应该足以知道这是一个TSqlScript
类;-(
关于"第二种情况":
var c0 = _list[0].Expression as ColumnReferenceExpression;
var c1 = _list[1].Expression as ColumnReferenceExpression;
我怎么可能把ExpressionWithSortOrders变成 列引用表达式?
但你没有。你把ExpressionWithSortOrder
类的Expression
属性变成了一个ColumnReferenceExpression
,根据文档,这是完全可以的,因为Expression
是ScalarExpression
类型,ColumnReferenceExpression
继承了它。