Criar provedores de fonte de dados tabulares para os Serviços PerformancePoint no SharePoint

Saiba como criar o componente de provedor de fonte de dados em uma extensão de fonte de dados tabular personalizada para os Serviços PerformancePoint.

Quais são os provedores de fontes de dados personalizados para PerformancePoint Services ?

Provedores de fonte de dados se conectar a uma fonte de dados, acesso a seus dados e resultados de consulta, em seguida, retorno. PerformancePoint Services usa os provedores de fontes de dados tabulares para acessar dados em planilhas de Excel e Serviços do Excel, listas do SharePoint e tabelas de Microsoft SQL Server. Pode criar um fornecedor de origem de dados personalizado para utilizar dados de uma origem de dados tabular que não é suportada por Serviços PerformancePoint.

A função principal de um provedor de fonte de dados tabulares é criar e preencher uma tabela de dados com dados da fonte de dados. Ele também cria mapeamentos de coluna para definir o tipo de dados que cada coluna contenha (fatos, dimensões ou dimensão de tempo). Isso se aplica a uma estrutura básica de multidimensional aos dados tabulares.

Os procedimentos e exemplos de código neste artigo baseiam-se na classe WSTabularDataSourceProvider do exemplo de objetos personalizados. O provedor recupera cotações de um serviço de web externa para os símbolos de ações especificados. Ele armazena dados de histórico cotações de ações em um arquivo de cache, que permite que os dados a ser dividido por vez. Para obter o código completo para a classe , veja Exemplo de código: Criar um fornecedor de origem de dados para origens de dados tabulares Serviços PerformancePoint personalizadas no SharePoint.

Recomendamos que você use o provedor de fonte de dados de amostra como um modelo. O exemplo mostra como chamar objetos em PerformancePoint Services API e demonstra as práticas recomendadas para o desenvolvimento de PerformancePoint Services.

Criar provedores de fonte de dados para personalizado PerformancePoint Services fontes de dados tabulares

  1. Install PerformancePoint Services, or copy the DLLs that your extension uses (listed in step 3) to your computer. Para obter instruções, veja DLLs com Bibliotecas de Classes.

  2. Em Visual Studio, crie uma biblioteca de classes c#. Se você já criou uma biblioteca de classes para sua extensão, adicione uma nova classe c#.

    You must sign your DLL with a strong name. In addition, ensure that all assemblies referenced by your DLL have strong names. Para obter informações sobre como assinar uma assemblagem com um nome forte e como criar um par de chaves públicas/privadas, consulte Como: Criar um Par de Chaves Públicas/Privadas.

  3. Adicione a seguinte PerformancePoint Services DLLs como referências de assembly para o projeto:

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

    O provedor de fonte de dados de amostra também contém referências de assembly System.Core.dll, System.ServiceModel.dll, System.Web.dll, System.Web.Services.dll e System.Xml.Linq.dll. Dependendo da funcionalidade da sua extensão, outras referências de projeto podem ser necessárias.

  4. Adicione uma referência de serviço chamada StockQuotes que referencia o serviço Web localizado no endereço http://www.webservicex.net/stockquote.asmx. Este é um serviço Web que fornece cotações para a fonte de dados de amostra.

  5. Adicione as classes BasicTabularDataSourceProvider e SampleDSCacheHandler da amostra ao seu projeto. BasicTabularDataSourceProvider herda da classe TabularDataSourceProvider , que é a classe base para provedores de fontes de dados tabulares.

    A origem de dados de exemplo também utiliza a classe como um contentor para os métodos abstratos substituídos que TabularDataSourceProvider não implementa ( GetDatabaseNames() , GetCubeNames() , GetCubeNameInfos() , GetCubeMetaData e Validate() ).

  6. Na sua classe de fornecedor, adicione using diretivas para os seguintes Serviços PerformancePoint espaços de nomes:

  1. Herde da classe BasicTabularDataSourceProvider.

  2. Declarar variáveis e definir propriedades que são usadas para análise, armazenamento e recuperação de símbolos de ações, o local do arquivo de cache e o URI do servidor proxy.

  3. Substitua a propriedade IsConnectionStringSecure . Esta propriedade não é utilizada por Serviços PerformancePoint, mas destina-se a aplicações personalizadas a utilizar opcionalmente para identificar se um cadeia de conexão expõe informações que podem representar um risco de segurança.

    Retornar true se sua extensão armazena informações confidenciais — como um nome de usuário ou senha — na sequência de conexão para sua fonte de dados. Devolver falso se não armazenar informações confidenciais ou se a origem de dados não utilizar um cadeia de conexão.

  4. Substitua o método GetId() para devolver o identificador exclusivo do seu fornecedor. GetId() tem de devolver a mesma cadeia que o atributo de chave registado no ficheiro de Serviços PerformancePoint web.config do fornecedor de origem de dados personalizado.

  5. Substitua o método SetDataSource para definir mapeamentos de colunas. SetDataSource chama o método CreateDataColumnMappings para definir colunas de fonte de dados como os tipos de Fact , Dimension e TimeDimension .

    SetDataSource também recupera os símbolos de ações, local do arquivo de cache e endereço do servidor proxy da propriedade CustomData do objeto de fonte de dados personalizados. Esses valores são definidos por autores de painel no editor de fonte de dados de amostra.

  6. Substitua o método GetDataSet() para criar um objeto DataSet para armazenar os dados da origem de dados. O provedor de fonte de dados de amostra usa os métodos FillResultsTable e GetLiveQuote para preencher uma tabela de dados com dados de um serviço Web.

Exemplo de código: Criar um fornecedor de origem de dados para origens de dados tabulares Serviços PerformancePoint personalizadas no SharePoint

A classe no exemplo de código a seguir cria um provedor de fonte de dados tabulares que recupera cotações de um serviço Web externo e, em seguida, transforma os dados em um formato tabular.

Antes de poder compilar este exemplo de código, tem de configurar o seu ambiente de desenvolvimento conforme descrito em Criar fornecedores de origens de dados para origens de dados de Serviços PerformancePoint tabulares personalizadas.

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
          && StockSymbols.Length > 0
          && !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 && 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
  }
}

Próximas etapas

Depois de criar um fornecedor de origem de dados e um editor de origem de dados (incluindo a respetiva interface de utilizador, se necessário), implemente a extensão conforme descrito em Como: Registar Manualmente Serviços PerformancePoint Extensões.

Confira também