Ключевое слово "as" считается ошибочным в коде TSql100Parser
Предположим, я хочу разобрать оператор SQL
SELECT foo, bar, baz FROM myTable WHERE baz = 2 ORDER BY baz ASC, bar DESC
и программно определить столбцы и направления, по которым он упорядочен. После некоторого поиска в Google вот что я придумал:
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());
}
}
Этот код работает нормально, но я нахожу его очень запутанным. Есть два места, где ключевое слово "как" мне кажется странным.
Первый из них находится на шестой строке. TsqlScript - это подкласс TSqlFragment, поэтому я думаю, что мне повезло, что я смог преобразовать его в подкласс. Но TSqlFragment, который является типом возврата метода Parse в строке 3, не имеет каких-либо полезных свойств, только его подкласс имеет полезные свойства. Так какой тип API предоставит класс, который будет полезен только в том случае, если вы знаете, что он может привести его к чему-то другому?
Второе и более запутанное использование "как" используется во внутреннем foreach. Как это возможно, что я превратил ExpressionWithSortOrders в ColumnReferenceExpressions? Это классы, а не интерфейсы, и они не наследуются друг от друга. Насколько я могу судить, они не имеют ни явного, ни неявного преобразования друг в друга.
В целом, как можно научиться работать с таким API? Я не нашел ничего об этом кастинге в официальной документации scriptdom. Visual Studio не говорит мне, что я могу превратить эти классы друг в друга.
1 ответ
По поводу "первого дела":
MSDN утверждает, что перегрузка Parse
метод, который вы используете
Возвращает фрагмент скрипта и список ошибок, используя предоставленные значения. (Унаследовано от TSqlParser.)
Я думаю, этого должно быть достаточно, чтобы понять, что это TSqlScript
учебный класс;-)
По поводу "второго дела":
var c0 = _list[0].Expression as ColumnReferenceExpression;
var c1 = _list[1].Expression as ColumnReferenceExpression;
Как это возможно, что я превратил ExpressionWithSortOrders в ColumnReferenceExpressions?
Но ты не сделал. Вы перевернули Expression
собственность ExpressionWithSortOrder
класс в ColumnReferenceExpression
что в соответствии с документами совершенно нормально, как Expression
имеет тип ScalarExpression
, а также ColumnReferenceExpression
наследует от этого.