Введение в SQL Server Analysis Services для разработчика. ADOMD.NET

Содержание предыдущей серии

Существуют средства доступа, берущие на себя накладные расходы, но, как и в любой программной модели, за это приходится платить снижением гибкости и полноты контроля. Наиболее популярным таким средством является ADOMD.NET – аналог ADO.NET для многомерных данных. Библиотека ADOMD.NET ставится в составе SQL Server, либо ее можно скачать и установить отдельно. Она раздается в составе SQL Server Feature Pack. Для SQL Server 2008 R2 ее на данный момент можно взять здесь (СТР3 – ноябрь 2009). Для просто SQL Server 2008 ее на данный момент можно взять здесь (октябрь 2009). Найдите в перечне фич Microsoft ADOMD.NET и скачайте. Для SQL Server 2005 тоже где-то есть.

Рассмотрим в качестве примера отправку XMLA-запроса с помощью ADOMD.NET.

Создайте новое консольное приложение. Предварительно в проект требуется добавить ссылку на C:\Program Files\Microsoft.NET\ADOMD.NET\100\Microsoft.AnalysisServices.AdomdClient.dll:

Рис. 1

Разрешите использование типов в пространстве имен Microsoft.AnalysisServices.AdomdClient:

Рис. 2

Запустите на выполнение код:

using System; 
using Microsoft.AnalysisServices.AdomdClient; 
using System.Diagnostics; 

class Program 
{ 
    static void Main(string[] args) 
    { 
        string xmla = @"<Statement>SELECT Measures.MEMBERS ON COLUMNS FROM [Adventure Works]</Statement>"; 
        AdomdConnection cnn = new AdomdConnection("Data Source=http://192.168.0.29/msolap/msmdpump.dll; User ID=192.168.0.29\\Administrator; Password=AbraCada<br>a"); 
        cnn.Open(); 
        AdomdCommand cmd = new AdomdCommand(xmla, cnn); 
        cmd.Properties.Add("Catalog", "Adventure Works DW 2008R2"); 
        cmd.Properties.Add("Format", "Multidimensional"); 
        cmd.Properties.Add("AxisFormat", "TupleFormat"); 
        CellSet res = cmd.ExecuteCellSet(); 
        cnn.Close(); 
        Debug.WriteLine(""); 
        foreach (Cell c in res.Cells) Debug.Write(String.Format("{0} ; ", c.FormattedValue)); 
        Debug.WriteLine("\n"); 
    } 
}

Скрипт 1

Для счастливчиков, успевших установить Visual Studio 2010 Release Candidate, - получите ошибку The type or namespace name 'AnalysisServices' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?). И это невзирая на то, что IntelliSence только что его прекрасно видел. Зайдите в свойства проекта и исправьте Target framework c .NET Framework 4 Client Profile, который VS по умолчанию ставит для консольных приложений и Win-форм, на полный .NET Framework 4:

Рис. 3

Об отличиях можно прочитать здесь.

Снова запустите приложение на выполнение. Теперь оно выполнится нормально

Рис. 4

и мы можем продолжить наш разговор про ADO.NET. Во-первых, ADOMD.NET предоставляет модель доступа, инвариантную по отношению к протоколу. В случае, когда в качестве Data Source выступает ISAPI dll (с префиксом http://), ADOMD.NET шлет SOAP-запрос по HTTP. Мы могли бы написать в качестве Data Source просто имя OLAP-сервера:

AdomdConnection cnn = new AdomdConnection("Data Source=192.168.0.29;"); 
cnn.Open();

Скрипт 2

В этом случае SOAP-запрос автоматически отправлялся бы по ТСР. Понятно, что когда на пути нет IISа, осуществляющего промежуточную аутентификацию, MS AS будет аутентифицировать по Windows credentials и указывать User ID; Password не требуется.

Во-вторых, обратите внимание на урезанный вид XMLA-запроса в Скрипте 1 по сравнению со Скриптом 1 из предыдущего поста. От него остался только элемент Statement:

<Statement>SELECT Measures.MEMBERS ON COLUMNS FROM [Adventure Works]</Statement>

Скрипт 3

Если попытаться запихать запрос в ADOMD.NET в его первоначальном полном варианте (см. Скрипт 1 из поста MDX и XMLA):

<soap:Envelope xmlns:soap='https://schemas.xmlsoap.org/soap/envelope/'> 
  <soap:Body> 
    <Execute xmlns='urn:schemas-microsoft-com:xml-analysis'> 
      <Command> 
        <Statement>SELECT Measures.MEMBERS ON COLUMNS FROM [Adventure Works]</Statement> 
      </Command> 
      <Properties> 
... 
</soap:Envelope>

Скрипт 4

произойдет ошибка The soap:Envelope element at line 7, column 85 (namespace https://schemas.xmlsoap.org/soap/envelope/) cannot appear under Envelope/Body/Execute/Command, из которой следует, что ADOMD.NET за нас заворачивает текст команды в SOAP-конверт. Следовательно, в качестве текста AdomdCommand потребляется InnerXml элемента Command XMLA-запроса. Что мы и видели на примере окна MDX-запроса в SSMS. См., напр., Рис.3 в посте XMLA DDL. Тот пример на команду резервного копирования можно выполнить из ADOMD.NET следующим образом:

cnn.Open(); 
AdomdCommand cmd = new AdomdCommand( 
@"<Backup xmlns='https://schemas.microsoft.com/analysisservices/2003/engine'>                  
    <Object> 
       <DatabaseID> Adventure Works DW 2008R2</DatabaseID> 
    </Object> 
    <File>Adventure Works DW.abf</File>  
    <AllowOverwrite>true</AllowOverwrite> 
  </Backup>", 
                             cnn); 
cmd.Execute(); 
cnn.Close();

Скрипт 5

Т.е. Inner XML из элемента Command, как и говорилось выше.

В случае MDX Query в SSMS для DML-запросов можно опускать не только скобки в виде элемента Command, но и вообще ограничиться Inner XML из элемента Statement. Так, от нашего первоначального SOAP XMLA-запросa (Скрипт 1 из поста MDX и XMLA) в результате остается только

Рис. 5

а в Скрипте 1, соответственно -

string xmla = "SELECT Measures.MEMBERS ON COLUMNS FROM [Adventure Works]"; 
...

Скрипт 6

Невозможность послать через ADOMD.NET полноценный XMLA-запрос, а только его подмножество в виде элемента Command вызывает некоторый дискомфорт. Внутри элемента Execute наряду с Command идут также Properties и Parameters (https://msdn.microsoft.com/en-us/library/ms186691.aspx). Если AdomdCommand оперирует только с внутренностью элемента Command, как передать ей свойства и параметры? Далее, как быть с методом Discover, про который еще толком не говорилось, только упоминалось, что он есть наравне с Execute? Он ведь вообще не имеет элемента Command. Там различие начинается на более высоком уровне. Что в этом случае выполнять в ADOMD.NET? Смотрите следующую серию.

Автор: Алексей Шуленин