Ключевое слово "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 наследует от этого.

Другие вопросы по тегам