Итак, продолжаем осваивать внутренности OLAP кубов (предыдущие статьи на эту тему: 1, 2, 3). На повестке дня актуальный вопрос: «А как можно достать OLAP куб программно?». Понимаю – теория-теорией, но если данные нельзя (или очень сложно) получать из кода, то грош цена таким технологиям. К счастью, здесь все очень просто – знаете ADO.NET? Ну, так это то же самое, только называется ADOMD.NET.
Как же так, скажите вы – еще одна библиотека, которую нужно изучать?! Вообщем-то, можно конечно и через OLEDB «доставать» куб (как-нибудь напишу, как это делать), но тогда теряется вся специфика многомерности, а сама библиотека ADOMD.NET достаточно простая, что я сейчас и покажу.
Итак, приступим.
Окружение
Как всегда начнем с окружения. Для сегодняшнего рецепта нам понадобится:
- Microsoft SQL Server, с запущенными Analysis Services (2005/2008);
- HabraCube, созданный в предыдущей статье (см. ниже);
- Visual Studio (2005/2008) или Visual C# 2008 Express Edition
- ADOMD.NET (9.0/10.0)
Если у вас нету Хабракуба, вы можете очень быстро его создать, прочитав следующую главу, остальным можно пропустить.
XMLA или быстро создаем Хабракуб
Если вы пользуетесь Microsoft SQL Server Management Studio, вы наверняка замечали ряд кнопочек для создания различных запросов, расположенный вверху:
Первые две кнопочки понятны, а вот следующие 3 скорее всего требуют пояснений:
- MDX Query – создает MDX запрос для выборки данных из куба (в первой статье из этой серии есть несколько примеров);
- DMX Query – нет, это не тавтология, DMX запросы предназначены для выборки данных из Data Mining структур;
- Нам понадобится именно последняя кнопка XMLA Query – XMLA — это, основанный на XML, язык управления аналитическими системами;
Например, в нашем случае, чтобы быстро создать Хабракуб, можно просто запустить XMLA запрос, скачав его отсюда.
Получилось? Теперь чтобы заполнить куб данными, скачайте мой старый SQL скрипт для создания Хабра-хранилища голосов. И запустите куб на процессинг — для этого подключите вашу Management Studio к Analysis Services, выберите Хабракуб а затем комманду Process в контекстном меню. Следует учесть, что, по-умолчанию, датасорс для куба – это локальное (local) хранилище HabraDW. Если вы хотите изменить строку подключения – откройте папку Data Sources вашего куба и измените параметры Habra DW.
Продолжаем…
ADOMD.NET
Библиотеку ADOMD.NET можно скачать со страницы Microsoft SQL Server 2008 Feature Pack:
- X86 Package (SQLSERVER2008_ASADOMD10.msi) — 4312 KB
- X64 Package (SQLSERVER2008_ASADOMD10.msi) — 9263 KB
- IA64 Package (SQLSERVER2008_ASADOMD10.msi) — 6776 KB
Hello World, часть 1
Итак, первое, что хочется сделать – это вычитать определение куба, тоесть из каких измерений и иерархий он состоит.
Создаем консольный C# проект, добавляем референс на ADOMD.NET:
И используем следующий код:
// prepare adomd connection
using (AdomdConnection mdConn = new AdomdConnection())
{
mdConn.ConnectionString = "provider=msolap;Data Source=(local);initial catalog=HabraCube;";
mdConn.Open();
// iterate through cubes
foreach (CubeDef cube in mdConn.Cubes)
{
if (cube.Type != CubeType.Cube) continue;
Console.WriteLine("*** Cube: " + cube.Name);
// iterate through dimensions
foreach (Dimension dimension in cube.Dimensions)
{
Console.WriteLine("-> Dimension: " + dimension.Name);
// iterate through hierarchies
foreach (Hierarchy hierarchy in dimension.Hierarchies)
{
Console.WriteLine("--> Hierarchy: " + hierarchy.Name);
// iterate through levels
foreach (Level level in hierarchy.Levels)
{
Console.WriteLine("---> Level: " + level.Name);
}
}
}
}
}
* This source code was highlighted with Source Code Highlighter.
Результат:
Достаточно прозрачно, не правда ли?
Hello World, часть 2
А теперь запустим MDX запрос и вычитаем результат. Для этого используем следующий код:
// prepare adomd connection
using (AdomdConnection mdConn = new AdomdConnection())
{
mdConn.ConnectionString = "provider=msolap;Data Source=(local);initial catalog=HabraCube;";
mdConn.Open();
AdomdCommand mdCommand = mdConn.CreateCommand();
mdCommand.CommandText = mdx; // << MDX Query
// work with CellSet
CellSet cs = mdCommand.ExecuteCellSet();
// our method supports only 2-Axes CellSets
if (cs.Axes.Count != 2) return;
TupleCollection tuplesOnColumns = cs.Axes[0].Set.Tuples;
TupleCollection tuplesOnRows = cs.Axes[1].Set.Tuples;
// output column headers
Console.Write("{0,-12}", "Item");
for (int col = 0; col < tuplesOnColumns.Count; col++)
{
Console.Write("{0,-12}", tuplesOnColumns[col].Members[0].Caption);
}
Console.WriteLine();
// output rows
for (int row = 0; row < tuplesOnRows.Count; row++)
{
Console.Write("{0,-12}", tuplesOnRows[row].Members[0].Caption);
// fill columns
for (int col = 0; col < tuplesOnColumns.Count; col++)
{
Console.Write("{0,-12}", cs.Cells[col, row].Value);
}
Console.WriteLine();
}
}
* This source code was highlighted with Source Code Highlighter.
Пробуем запустить следующий MDX запрос:
SELECT
{[Measures].[Vote], [Measures].[Votes Count]} ON COLUMNS,
[Dim Time].[Month Name].MEMBERS ON ROWS
FROM [HabraCube]
* This source code was highlighted with Source Code Highlighter.
Результат:
Исходный проект можно найти по этой ссылке.