Поделиться через


Создание таблиц, секций и столбцов в табличной модели

Применимо к: SQL Server 2016 и более поздних версий Analysis Services Azure Analysis Services Fabric/Power BI Premium

В табличной модели таблица состоит из строк и столбцов. Строки организованы в секции для поддержки добавочного обновления данных. Табличное решение может поддерживать несколько типов таблиц в зависимости от того, откуда поступают данные:

  • Обычные таблицы, в которых данные исходят из реляционного источника данных через поставщик данных.

  • Отправленные таблицы, в которых данные "отправляются" в таблицу программным способом.

  • Вычисляемые таблицы, в которых данные поступают из выражения DAX, которое ссылается на другой объект в модели для своих данных.

В приведенном ниже примере кода мы определим обычную таблицу.

Обязательные элементы

Таблица должна содержать по крайней мере одну секцию. В обычной таблице также должен быть определен по крайней мере один столбец.

У каждой секции должен быть источник, указывающий источник данных, но источнику можно присвоить значение NULL. Как правило, источником является выражение запроса, определяющее срез данных на соответствующем языке запросов базы данных.

Пример кода: создание таблицы, столбца, секции

Таблицы представлены классом Table (в пространстве имен Microsoft.AnalysisServices.Tabular).

В приведенном ниже примере мы определим обычную таблицу с одной секцией, связанной с реляционным источником данных, и несколькими регулярными столбцами. Мы также отправим изменения на сервер и активируем обновление данных, которое переносит данные в модель. Это наиболее типичный сценарий, когда требуется загрузить данные из SQL Server реляционной базы данных в табличное решение.

using System; 
using Microsoft.AnalysisServices; 
using Microsoft.AnalysisServices.Tabular; 
 
namespace TOMSamples 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            // 
            // Connect to the local default instance of Analysis Services 
            // 
            string ConnectionString = "DataSource=localhost"; 
 
            // 
            // The using syntax ensures the correct use of the 
            // Microsoft.AnalysisServices.Tabular.Server object. 
            // 
            using (Server server = new Server()) 
            { 
                server.Connect(ConnectionString); 
 
                // 
                // Generate a new database name and use GetNewName 
                // to ensure the database name is unique. 
                // 
                string newDatabaseName = 
                    server.Databases.GetNewName("Database with a Table Definition"); 
 
                // 
                // Instantiate a new  
                // Microsoft.AnalysisServices.Tabular.Database object. 
                // 
                var dbWithTable = new Database() 
                { 
                    Name = newDatabaseName, 
                    ID = newDatabaseName, 
                    CompatibilityLevel = 1200, 
                    StorageEngineUsed = StorageEngineUsed.TabularMetadata, 
                }; 
 
                // 
                // Add a Microsoft.AnalysisServices.Tabular.Model object to the 
                // database, which acts as a root for all other Tabular metadata objects. 
                // 
                dbWithTable.Model = new Model() 
                { 
                    Name = "Tabular Data Model", 
                    Description = "A Tabular data model at the 1200 compatibility level." 
                }; 
 
                // 
                // Add a Microsoft.AnalysisServices.Tabular.ProviderDataSource object 
                // to the data Model object created in the previous step. The connection 
                // string of the data source object in this example  
                // points to an instance of the AdventureWorks2014 SQL Server database. 
                // 
                string dataSourceName = "SQL Server Data Source Example"; 
                dbWithTable.Model.DataSources.Add(new ProviderDataSource() 
                { 
                    Name = dataSourceName, 
                    Description = "A data source definition that uses explicit Windows credentials for authentication against SQL Server.", 
                    ConnectionString = "Provider=SQLNCLI11;Data Source=localhost;Initial Catalog=AdventureWorks2014;Integrated Security=SSPI;Persist Security Info=false", 
                    ImpersonationMode = Microsoft.AnalysisServices.Tabular.ImpersonationMode.ImpersonateAccount, 
                    Account = @".\Administrator", 
                    Password = "P@ssw0rd", 
                }); 
 
                //  
                // Add a table called Individual Customers to the data model 
                // with a partition that points to a [Sales].[vIndividualCustomer] view 
                // in the underlying data source. 
                // 
                dbWithTable.Model.Tables.Add(new Table() 
                { 
                    Name = dbWithTable.Model.Tables.GetNewName("Individual Customers"), 
                    Description = "Individual customers (names and email addresses) that purchase Adventure Works Cycles products online.", 
                    Partitions = { 
                        // 
                        // Create a single partition with a QueryPartitionSource for a query 
                        // that imports all customer rows from the underlying data source. 
                        // 
                        new Partition() { 
                            Name = "All Customers", 
                            Source = new QueryPartitionSource() { 
                                DataSource = dbWithTable.Model.DataSources[dataSourceName], 
                                Query = @"SELECT   [FirstName] 
                                                    ,[MiddleName] 
                                                    ,[LastName] 
                                                    ,[PhoneNumber]  
                                                    ,[EmailAddress] 
                                                    ,[City] 
                                        FROM [Sales].[vIndividualCustomer]", 
                            } 
                        } 
                    }, 
                    Columns = 
                    { 
                        // 
                       // DataColumn objects refer to regular table columns.  
                        // Each DataColumn object corresponds to a column in the underlying data source query. 
                        // 
                        new DataColumn() { 
                            Name = "FirstName", 
                            DataType = DataType.String, 
                            SourceColumn = "FirstName", 
                        }, 
                        new DataColumn() { 
                            Name = "MiddleName", 
                            DataType = DataType.String, 
                            SourceColumn = "MiddleName", 
                        }, 
                        new DataColumn() { 
                            Name = "LastName", 
                            DataType = DataType.String, 
                            SourceColumn = "LastName", 
                        }, 
                        new DataColumn() { 
                            Name = "PhoneNumber", 
                            DataType = DataType.String, 
                            SourceColumn = "PhoneNumber", 
                        }, 
                        new DataColumn() { 
                            Name = "EmailAddress", 
                            DataType = DataType.String, 
                            SourceColumn = "EmailAddress", 
                        }, 
                        new DataColumn() { 
                            Name = "City", 
                            DataType = DataType.String, 
                            SourceColumn = "City", 
                        }, 
                    } 
                }); 
 
                // 
                // Add the new database object to the server's  
                // Databases connection and submit the changes 
                // with full expansion to the server. 
                // 
                server.Databases.Add(dbWithTable); 
 
                //  
                // Request a full refresh to import the data from the data source and 
                // and perform any necessary recalculations. 
                // The refresh operation will be performed with the next 
                // invocation of Model.SaveChanges() or Database.Update(UpdateOptions.ExpandFull). 
                dbWithTable.Model.RequestRefresh(Microsoft.AnalysisServices.Tabular.RefreshType.Full); 
                dbWithTable.Update(UpdateOptions.ExpandFull); 
 
 
                Console.Write("Database "); 
                Console.ForegroundColor = ConsoleColor.Yellow; 
                Console.Write(dbWithTable.Name); 
                Console.ResetColor(); 
                Console.WriteLine(" created successfully."); 
 
                Console.WriteLine("The data model includes the following table definitions:"); 
                Console.ForegroundColor = ConsoleColor.Yellow; 
                foreach (Table tbl in dbWithTable.Model.Tables) 
                { 
                    Console.WriteLine("\tTable name:\t\t{0}", tbl.Name); 
                    Console.WriteLine("\ttbl description:\t{0}", tbl.Description); 
                } 
                Console.ResetColor(); 
                Console.WriteLine(); 
            } 
            Console.WriteLine("Press Enter to close this console window."); 
            Console.ReadLine(); 
        } 
    } 
} 

Секции в таблице

Секции представлены классом Partition (в пространстве имен Microsoft.AnalysisServices.Tabular). Класс Partition предоставляет свойство Source типа PartitionSource , которое обеспечивает абстракцию при различных подходах к приему данных в секцию. Экземпляр секции может иметь свойство Source в качестве значения NULL, указывающее, что данные будут отправляться в секцию путем отправки фрагментов данных на сервер в рамках API push-уведомлений, предоставляемого службами Analysis Services. В SQL Server 2016 году класс PartitionSource имеет два производных класса, представляющих способы привязки данных к секции: QueryPartitionSource и CalculatedPartitionSource.

Столбцы в таблице

Столбцы представлены несколькими классами, производными от базового класса Column (в пространстве имен Microsoft.AnalysisServices.Tabular):

  • DataColumn (для обычных столбцов в обычных таблицах)
  • CalculatedColumn (для столбцов, подкрепленных выражением DAX)
  • CalculatedTableColumn (для обычных столбцов в вычисляемых таблицах)
  • RowNumberColumn (специальный тип столбца, созданного службой SSAS для каждой таблицы).

Номера строк в таблице

Каждый объект Table на сервере имеет объект RowNumberColumn , используемый для индексирования. Вы не можете создать или добавить его явным образом. Столбец создается автоматически при сохранении или обновлении объекта :

  • Db. Savechanges

  • Db. Update(ExpandFull)

При вызове любого из методов сервер автоматически создаст столбец с номерами строк, который будет отображаться как RowNumberColumn коллекции Столбцы таблицы.

Вычисляемые таблицы

Вычисляемые таблицы извлекаются из выражения DAX, которое повторно использует данные из существующих структур данных в модели или из внестроковых привязок. Чтобы создать вычисляемую таблицу программным способом, выполните следующие действия.

  • Создайте универсальную таблицу.

  • Добавьте в него секцию с типом Source CalculatedPartitionSource, где источником является выражение DAX. Источник секции отличает обычную таблицу от вычисляемой таблицы.

При сохранении изменений на сервере сервер вернет выводимый список CalculatedTableColumns (вычисляемые таблицы состоят из вычисляемых столбцов таблицы), видимый через коллекцию Столбцы таблицы.

Следующий шаг

Просмотрите классы, используемые для обработки исключений в TOM: Обработка ошибок в TOM