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


Создание поставщиков источников табличных данных для PerformancePoint Services в SharePoint

Узнайте, как создать компонент поставщика источника данных в расширении источников специальных табличных данных для PerformancePoint Services.

Что такое настраиваемых поставщиков источников данных для Службы PerformancePoint Services ?

Поставщики источников данных подключения к источнику данных, доступ к данным и затем возврата результатов. Службы PerformancePoint Services использует поставщиков табличных источников данных для доступа к данным из Excel и Службы Excel листы, списки SharePoint и Microsoft SQL Server таблицы. Можно создать поставщика настраиваемого источника данных, чтобы использовать данные из источника табличных данных, не поддерживаемый Службы PerformancePoint Services.

Основная функция поставщика источника табличных данных — создание и заполнение таблицу данных с данными из источника данных. Он также создает сопоставления столбцов, чтобы определить тип данных, что каждый столбец содержит (фактов, измерений или измерение времени). Базовая структура многомерные применяется к табличных данных.

Инструкции и примеры кода в этом разделе основаны на класс WSTabularDataSourceProvider из настраиваемых объектов. Поставщик извлекает акций внешних веб-службе для указанного символов акций. Хранит данные журнала запасов квоты в файл кэша, который позволяет данные срез по времени. Полный код для класса см. в разделе Пример кода. Создание поставщика источников данных для пользовательских PerformancePoint Services табличных источников данных в SharePoint.

Мы рекомендуем использовать примера поставщика источника данных в качестве шаблона. В примере показано, как вызывать объекты в Службы PerformancePoint Services API и демонстрируется советы и рекомендации по разработке Службы PerformancePoint Services.

Создание поставщики источников данных для настраиваемых Службы PerformancePoint Services табличные источники данных

  1. Установка Службы PerformancePoint Services или копирование библиотеки DLL, которые использует расширения (перечисленных в шаге 3) на своем компьютере. Инструкции см. в разделе Библиотеки DLL с библиотеками классов.

  2. В Visual Studio создайте библиотеку классов C#. Если библиотека классов для расширения уже создана, добавьте новый класс C#.

    DLL-библиотеку необходимо подписать строгим именем. Кроме того, убедитесь, что все сборки, на которые ссылается DLL-библиотека, имеют строгие имена. Сведения о том, как подписать сборку со строгим именем и как создать пару открытого и закрытого ключей, см. в разделе Практическое руководство. Создание пары открытого и закрытого ключей.

  3. Добавьте следующие Службы PerformancePoint Services библиотеки DLL в качестве ссылок на сборки в проект:

  • Microsoft.PerformancePoint.Scorecards.Client.dll

  • Microsoft.PerformancePoint.Scorecards.DataSourceProviders.Standard.dll

    В этом примере поставщика данных также используются ссылки на сборки System.Core.dll, System.ServiceModel.dll, System.Web.dll, System.Web.Services.dll и System.Xml.Linq.dll. В зависимости от функциональных возможностей расширения могут потребоваться другие сборки.

  1. Добавьте ссылку на службу с именем StockQuotes, которая ссылается на веб-службу, расположенную по адресу http://www.webservicex.net/stockquote.asmx. Эта веб-служба предоставляет котировки акций для примера поставщика источника данных.

  2. Добавьте классы BasicTabularDataSourceProvider и SampleDSCacheHandler из примера в проект. Класс BasicTabularDataSourceProvider наследуется от класса TabularDataSourceProvider , который является базовым для поставщиков табличных источников данных.

    Пример источника данных также использует класс в качестве контейнера для переопределенных абстрактных методов, которые TabularDataSourceProvider не реализует ( GetDatabaseNames() , GetCubeNames() , GetCubeNameInfos() , GetCubeMetaData и Validate() ).

  3. В классе поставщика добавьте директивы using для следующих пространств имен Службы PerformancePoint Services.

  1. Наследуется от класса BasicTabularDataSourceProvider.

  2. Объявите переменные и определите свойства, которые используются для синтаксического анализа, хранения и извлечения символов акций, местоположения файла кэша и идентификатора URI прокси-сервера.

  3. Переопределите свойство IsConnectionStringSecure . Это свойство не используется Службы PerformancePoint Services, но он предназначен для пользовательских приложений при необходимости использовать для определения, является ли строка подключения предоставляет сведения, которые могут привести к риску.

    Задайте возврат значения true, если в строке подключения к источнику данных в расширении содержатся конфиденциальные сведения, например, имя пользователя или пароль. Задайте возврат значения false, если конфиденциальные сведения не хранятся, или источник данных не использует строку подключения.

  4. Переопределите метод GetId(), чтобы вернуть уникальный идентификатор поставщика. GetId() должен возвращать ту же строку в качестве атрибута key, который зарегистрирован в файле web.config Службы PerformancePoint Services для поставщика настраиваемого источника данных.

  5. Переопределите метод SetDataSource , чтобы определить сопоставления столбцов. Метод SetDataSource вызывает метод CreateDataColumnMappings, чтобы определить столбцы источника данных как типы Fact , Dimension и TimeDimension .

    Метод SetDataSource также извлекает символы акций, местоположение файла кэша и адрес прокси-сервера из свойства CustomData объекта настраиваемого источника данных. Эти значения определяются автором панели мониторинга в редакторе примера источника данных.

  6. Переопределите метод GetDataSet(), чтобы создать объект DataSet для хранения данных из источника данных. В примере источника данных для заполнения таблицы данными из веб-службы используются методы FillResultsTable и GetLiveQuote.

Пример кода. Создание поставщика источников данных для пользовательских PerformancePoint Services табличных источников данных в SharePoint

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

Прежде чем скомпилировать этот пример кода, необходимо настроить среду разработки, как описано в разделе Создание поставщиков источников данных для пользовательских PerformancePoint Services табличных источников данных.


using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.PerformancePoint.Scorecards;
using Microsoft.PerformancePoint.Scorecards.ServerCommon;
using Microsoft.PerformancePoint.SDK.Samples.StockQuotes;
using System.ServiceModel;

namespace Microsoft.PerformancePoint.SDK.Samples.SampleDataSource
{

    // Represents the class that defines the sample data source provider.
    // It inherits from the BasicTabularDataSourceProvider class, which
    // contains overridden abstract methods that are not implemented.
    public class WSTabularDataSourceProvider : BasicTabularDataSourceProvider
    {
        #region Constants
        private const int StockSymbolsIndex = 0;
        private const int CacheFileLocationIndex = 1;
        private const int ProxyAddressIndex = 2;
        #endregion

        #region Properties

        // This property stores the stock symbols that are used
        // to query the Web service.
        // Its value is obtained by parsing the CustomData property
        // of the data source object. 
        private string[] StockSymbols
        {
            get;
            set;
        }

        // The address of the proxy server.
        private Uri ProxyAddress
        {
            get;
            set;
        }

        // This property is not used by PerformancePoint Services.
        // Its intended use is for custom applications to indicate
        // whether a provider stores sensitive information in the
        // connection string, such as user name and password.
        // This sample does not, so it returns false. 
        public override bool IsConnectionStringSecure
        {
            get { return false; }
        }
        #endregion

        #region Overridden methods

        // The source name for your data source. This value must match the key
        // attribute that is registered in the web.config file.
        public override string GetId()
        {
            return "WSTabularDataSource";
        }

        // Add column mappings for the sample columns if they do not exist.
        // Column mappings may be missing if the custom data source has never
        // been edited or if the workspace was not refreshed, which saves
        // changes to the server.
        public override void SetDataSource(DataSource dataSource)
        {

            base.SetDataSource(dataSource);

            // Check for symbols stored in the CustomData
            // property of the data source.
            if (null == dataSource ||
                 string.IsNullOrEmpty(dataSource.CustomData))
            {

                // Create a symbol for testing purposes.
                StockSymbols = new[] { "MSFT" };
            }
            else
            {
                string[] splitCustomData = dataSource.CustomData.Split('&');
                if (splitCustomData.Length > 2)
                {
                    StockSymbols = splitCustomData[StockSymbolsIndex].ToUpper().Split(',');
                    for (int iLoop = 0; iLoop < StockSymbols.Length; iLoop++)
                    {
                        StockSymbols[iLoop] = StockSymbols[iLoop].Trim();
                    }

                    SampleDSCacheHandler.CacheFileLocation = splitCustomData[CacheFileLocationIndex];
                    ProxyAddress = new Uri(splitCustomData[ProxyAddressIndex]);
                }
            }

            // Check whether column mappings exist. Do not overwrite them.
            if (dataSource.DataTableMapping.ColumnMappings.Count == 0)
            {
                dataSource.DataTableMapping = CreateDataColumnMappings();
            }
        }

        // Get the data from the data source.
        // GetDataSet contains the core logic for the provider.
        public override DataSet GetDataSet()
        {

            // Create a dataset and a data table to store the data.
            DataSet resultSet = new DataSet();
            DataTable resultTable = resultSet.Tables.Add();

            // Define column names and the type of data that they contain. 
            resultTable.Columns.Add("Symbol", typeof(string));
            resultTable.Columns.Add("Value", typeof(float));
            resultTable.Columns.Add("P-E Ratio", typeof(float));
            resultTable.Columns.Add("Percentage Change", typeof(float));
            resultTable.Columns.Add("Date", typeof(DateTime));

            FillResultTable(ref resultTable);

            return resultSet;
        }
        #endregion

        #region Internal methods

        // Fill the data table with the stock quote values from
        // the Web service and local cache file.
        protected void FillResultTable(ref DataTable resultsTable)
        {

            // Check the sematic validity of symbols (out of scope for this sample).
            if (null != StockSymbols &amp;&amp;
                StockSymbols.Length > 0 &amp;&amp;
                !string.IsNullOrEmpty(SampleDSCacheHandler.CacheFileLocation))
            {
                try
                {
                    if (!File.Exists(SampleDSCacheHandler.CacheFileLocation))
                    {

                        // Create the cache file.
                        XDocument doc = SampleDSCacheHandler.DefaultCacheFileContent;
                        doc.Save(@SampleDSCacheHandler.CacheFileLocation);
                    }

                    // Get real-time quotes and update cache file.
                    string wsResult = GetLiveQuote();

                    SampleDSCacheHandler.UpdateXMLCacheFile(wsResult);

                    // Check if a valid cache file location exists.
                    if (SampleDSCacheHandler.CacheFileContent != null)
                    {
                        var query = from c in SampleDSCacheHandler.CacheFileContent.Elements("StockQuotes").Elements("StockQuote")
                                    where StockSymbols.Contains(c.Attribute("Symbol").Value)
                                    select c;

                        foreach (var stockQuote in query)
                        {
                            DataRow row = resultsTable.NewRow();
                            row["Symbol"] = stockQuote.Attribute("Symbol").Value;
                            row["Value"] = stockQuote.Element("Value").Value;
                            row["Percentage Change"] = stockQuote.Element("PercentageChange").Value;
                            row["Date"] = stockQuote.Element("Date").Value;

                            decimal peRatio;

                            // Handle symbols that return 'N/A' for this field.
                            if (decimal.TryParse(stockQuote.Element("PERatio").Value, out peRatio))
                            {
                                row["P-E Ratio"] = peRatio;
                            }

                            resultsTable.Rows.Add(row);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ServerUtils.HandleException(ex);
                }
            }
        }

        // Get real-time quotes from the Web service.
        protected string GetLiveQuote()
        {
            EndpointAddress endpoint = new EndpointAddress("http://www.webservicex.net/stockquote.asmx");
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.ReceiveTimeout = new TimeSpan(0, 0, 120);
            binding.ProxyAddress = ProxyAddress;
            binding.UseDefaultWebProxy = false;

            StockQuotes.StockQuoteSoapClient wsStockQuoteService = new StockQuoteSoapClient(binding, endpoint);

            // Check the sematic validity of symbols (out of scope for this sample).
            if (null != StockSymbols &amp;&amp;
                StockSymbols.Length > 0)
            {
                try
                {
                    string quoteRequest = StockSymbols[0];
                    for (int iLoop = 1; iLoop < StockSymbols.Length; iLoop++)
                    {
                        quoteRequest = string.Format("{0}, {1}", quoteRequest, StockSymbols[iLoop]);
                    }

                    string wsResult = wsStockQuoteService.GetQuote(quoteRequest);
                    return wsResult;
                }
                catch (Exception ex)
                {
                    ServerUtils.HandleException(ex);
                }
            }
            return string.Empty;
        }

        // Create the column mappings.
        internal static DataTableMapping CreateDataColumnMappings()
        {
            DataTableMapping dtTableMapping = new DataTableMapping();

            // Define the data in the Symbol column as dimension data.
            dtTableMapping.ColumnMappings.Add(new DataColumnMapping
            {
                SourceColumnName = "Symbol",
                FriendlyColumnName = "Symbol",
                UniqueName = "Symbol",
                ColumnType = MappedColumnTypes.Dimension,
                FactAggregation = FactAggregations.None,
                ColumnDataType = MappedColumnDataTypes.String
            });

            // Define the data in the Value column as fact data.
            dtTableMapping.ColumnMappings.Add(new DataColumnMapping
            {
                SourceColumnName = "Value",
                FriendlyColumnName = "Value",
                UniqueName = "Value",
                ColumnType = MappedColumnTypes.Fact,
                FactAggregation = FactAggregations.Average,
                ColumnDataType = MappedColumnDataTypes.Number
            });

            // Define the data in the P-E Ratio column as fact data.
            dtTableMapping.ColumnMappings.Add(new DataColumnMapping
            {
                SourceColumnName = "P-E Ratio",
                FriendlyColumnName = "P-E Ratio",
                UniqueName = "P-E Ratio",
                ColumnType = MappedColumnTypes.Fact,
                FactAggregation = FactAggregations.Average,
                ColumnDataType = MappedColumnDataTypes.Number
            });

            // Define the data in the Percentage Change column as fact data.
            dtTableMapping.ColumnMappings.Add(new DataColumnMapping
            {
                SourceColumnName = "Percentage Change",
                FriendlyColumnName = "Percentage Change",
                UniqueName = "Percentage Change",
                ColumnType = MappedColumnTypes.Fact,
                FactAggregation = FactAggregations.Average,
                ColumnDataType = MappedColumnDataTypes.Number
            });

            // Define the Date column as a time dimension.
            dtTableMapping.ColumnMappings.Add(new DataColumnMapping
            {
                SourceColumnName = "Date",
                FriendlyColumnName = "Date",
                UniqueName = "Date",
                ColumnType = MappedColumnTypes.TimeDimension,
                FactAggregation = FactAggregations.None,
                ColumnDataType = MappedColumnDataTypes.DateTime
            });

            // Increase the granularity of the time dimension.
            dtTableMapping.DateAggregationType |= DateAggregationTypes.Quarter;
            dtTableMapping.DateAggregationType |= DateAggregationTypes.Month;
            dtTableMapping.DateAggregationType |= DateAggregationTypes.Week;
            dtTableMapping.DateAggregationType |= DateAggregationTypes.Day;

            return dtTableMapping;
        }
        #endregion
    }
}

Дальнейшие действия

После создания поставщика источника данных и редактора источника данных (включая его пользовательский интерфейс, если это необходимо), разверните расширение, как описано в разделе Практическое руководство. Регистрация расширений PerformancePoint Services вручную.

См. также