"as" 关键字在 TSql100Parser 代码中被认为是混淆的
"as" keyword considered confusing in TSql100Parser code
假设我要解析 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 的子class,所以我想我很幸运能够将它转换为子class.但是第3行Parse方法的return类型的TSqlFragment没有任何有用的属性,只有它的subclass有有用的属性。那么什么样的 API 会公开一个 class 只有在您碰巧知道将其转换为其他东西时才有用的东西?
"as" 的第二个也是更容易混淆的用法是在内部 foreach 中使用。我怎么可能将 ExpressionWithSortOrders 变成 ColumnReferenceExpressions?它们是 classes,不是接口,它们不相互继承。据我所知,它们之间既没有显式转换也没有隐式转换。
更一般地说,如何才能学会与这样的 API 一起工作?我没有在官方 scriptdom 文档中找到任何关于此转换的信息。 Visual Studio 并没有告诉我可以将这些 class 相互转化。
关于"first case":
MSDN 指出您使用的 Parse
方法的重载
Returns a script fragment and a list of errors by using the provided
values. (Inherited from TSqlParser.)
所以我想应该足以知道它是 TSqlScript
class ;-)
关于 "second case":
var c0 = _list[0].Expression as ColumnReferenceExpression;
var c1 = _list[1].Expression as ColumnReferenceExpression;
How is it possible that I've turned ExpressionWithSortOrders into
ColumnReferenceExpressions?
但你没有。您将 ExpressionWithSortOrder
class 的 Expression
属性 变成了 ColumnReferenceExpression
,根据 docs 完全可以,因为 Expression
属于 ScalarExpression
类型,ColumnReferenceExpression
继承自该类型。
假设我要解析 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 的子class,所以我想我很幸运能够将它转换为子class.但是第3行Parse方法的return类型的TSqlFragment没有任何有用的属性,只有它的subclass有有用的属性。那么什么样的 API 会公开一个 class 只有在您碰巧知道将其转换为其他东西时才有用的东西?
"as" 的第二个也是更容易混淆的用法是在内部 foreach 中使用。我怎么可能将 ExpressionWithSortOrders 变成 ColumnReferenceExpressions?它们是 classes,不是接口,它们不相互继承。据我所知,它们之间既没有显式转换也没有隐式转换。
更一般地说,如何才能学会与这样的 API 一起工作?我没有在官方 scriptdom 文档中找到任何关于此转换的信息。 Visual Studio 并没有告诉我可以将这些 class 相互转化。
关于"first case":
MSDN 指出您使用的 Parse
方法的重载
Returns a script fragment and a list of errors by using the provided values. (Inherited from TSqlParser.)
所以我想应该足以知道它是 TSqlScript
class ;-)
关于 "second case":
var c0 = _list[0].Expression as ColumnReferenceExpression;
var c1 = _list[1].Expression as ColumnReferenceExpression;
How is it possible that I've turned ExpressionWithSortOrders into ColumnReferenceExpressions?
但你没有。您将 ExpressionWithSortOrder
class 的 Expression
属性 变成了 ColumnReferenceExpression
,根据 docs 完全可以,因为 Expression
属于 ScalarExpression
类型,ColumnReferenceExpression
继承自该类型。