Compartir a través de


Crear proveedores de fuentes de datos tabulares para PerformancePoint Services en SharePoint

Aprenda a crear el componente de proveedor de fuentes de datos en una extensión de fuente de datos tabulares personalizada para PerformancePoint Services.

¿Qué son los proveedores de orígenes de datos personalizados para PerformancePoint Services?

Los proveedores de orígenes de datos conectan con un origen de datos, acceden a sus datos y, después, devuelven los resultados de la consulta. PerformancePoint Services usa proveedores de orígenes de datos tabulares para acceder a los datos desde hojas de cálculo de Excel y Servicios de Excel, listas de SharePoint y tablas de Microsoft SQL Server. Puede crear un proveedor de orígenes de datos personalizados para usar los datos de un origen de datos tabular no admitido por PerformancePoint Services.

La principal función de un proveedor de orígenes de datos tabulares es crear y rellenar una tabla de datos con los datos del origen de datos. También crea asignaciones de columnas para definir el tipo de datos que contiene cada columna (hecho, dimensión o dimensión temporal). Esto aplica a una estructura multidimensional básica a los datos tabulares.

El procedimiento y los ejemplos de código de este tema se basan en la clase WSTabularDataSourceProvider de la muestra de objetos personalizados. El proveedor recupera las cotizaciones de un servicio web externo para los símbolos de cotización especificados. Almacena los datos del histórico de cotizaciones en un archivo caché, lo que permite separar los datos por tiempo. Para obtener el código completo de la clase, vea Ejemplo de código: Creación de un proveedor de orígenes de datos para orígenes de datos tabulares personalizados PerformancePoint Services en SharePoint.

Recomendamos que use la muestra de proveedor de orígenes de datos como plantilla. La muestra indica cómo llamar a los objetos de la API de PerformancePoint Services así como los procedimientos recomendados para desarrollar con PerformancePoint Services.

Crear proveedores de orígenes de datos para orígenes de datos tabulares de PerformancePoint Services personalizados

  1. Instale PerformancePoint Services o copie los DLL que la extensión usa (enumerados en el paso 3) en el equipo. Para obtener instrucciones, vea ARCHIVOS DLL con bibliotecas de clases.

  2. En Visual Studio, cree una biblioteca de clases de C#. Si ya ha creado una biblioteca de clases para su extensión, agregue una nueva clase de C#.

    Debe firmar su DLL con un nombre seguro. Además, asegúrese de que todos los ensamblados a los que su DLL hace referencia tengan nombres seguros. Para obtener información sobre cómo firmar un ensamblado con un nombre seguro y cómo crear un par de claves pública y privada, vea How to: Create a Public/Private Key Pair.

  3. Agregue los siguientes archivos DLL de PerformancePoint Services como referencias de ensamblado al proyecto:

  • Microsoft.PerformancePoint.Scorecards.Client.dll

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

    El proveedor de orígenes de datos de muestra también contiene referencias de ensamblado a System.Core.dll, System.ServiceModel.dll, System.Web.dll, System.Web.Services.dll y System.Xml.Linq.dll. Según la funcionalidad de su extensión, podrían ser necesarias otras referencias de proyecto.

  1. Agregue una referencia de servicio denominada StockQuotes que haga referencia al servicio web ubicado en la dirección http://www.webservicex.net/stockquote.asmx. Este es el servicio web que proporciona las cotizaciones para el origen de datos de muestra.

  2. Agregue las clases BasicTabularDataSourceProvider y SampleDSCacheHandler de la muestra a su proyecto. BasicTabularDataSourceProvider hereda de la clase TabularDataSourceProvider , que es la clase base para los proveedores de orígenes de datos tabulares.

    El origen de datos de ejemplo también usa la clase como contenedor para los métodos abstractos invalidados que TabularDataSourceProvider no implementa ( GetDatabaseNames(),GetCubeNames(),GetCubeNameInfos() , GetCubeMetaData y Validate() ).

  3. En su clase de proveedor, agregue directivas using para los siguientes espacios de nombres de PerformancePoint Services:

  1. Herede de la clase BasicTabularDataSourceProvider.

  2. Declare las variables y defina las propiedades que se usan para analizar, almacenar y recuperar los símbolos de cotizaciones, la ubicación del archivo de caché y el URI del servidor proxy.

  3. Invalide la propiedad IsConnectionStringSecure . PerformancePoint Services no usa esta propiedad, pero está destinada a aplicaciones personalizadas que la pueden usar opcionalmente para identificar si una cadena de conexión expone información que podría suponer un riesgo para la seguridad.

    Devuelve true si la extensión almacena información confidencial (como un nombre de usuario o contraseña) en la cadena de conexión del origen de datos. Devuelve false si no almacena información confidencial o si el origen de datos no usa una cadena de conexión.

  4. Invalide el método GetId() para devolver el identificador único del proveedor. GetId() debe devolver la misma cadena que el atributo key que está registrado en el archivo web.config de PerformancePoint Services para el proveedor de orígenes de datos personalizado.

  5. Invalide el método SetDataSource para definir asignaciones de columnas. SetDataSource llama al método CreateDataColumnMappings para definir las columnas del origen de datos como tipos Fact , Dimension y TimeDimension .

    SetDataSource también recupera los símbolos de cotizaciones, la ubicación del archivo de caché y la dirección del servidor proxy de la propiedad CustomData del objeto de origen de datos personalizado. Estos valores son definidos por los autores del panel en el editor de orígenes de datos de muestra.

  6. Invalide el método GetDataSet() para crear un objeto DataSet para almacenar los datos del origen de datos. El proveedor de orígenes de datos de muestra usa los métodos FillResultsTable y GetLiveQuote para rellenar una tabla de datos con los datos de un servicio web.

Ejemplo de código: Creación de un proveedor de orígenes de datos para orígenes de datos tabulares personalizados PerformancePoint Services en SharePoint

La clase del siguiente ejemplo de código crea un proveedor de orígenes de datos tabulares que recupera las cotizaciones de un servicio web externo y luego transforma los datos en un formato tabular.

Para poder compilar este ejemplo de código, debe configurar el entorno de desarrollo como se describe en Creación de proveedores de orígenes de datos para orígenes de datos tabulares personalizados 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
    }
}

Pasos siguientes

Después de crear un proveedor de origen de datos y un editor de origen de datos (incluida su interfaz de usuario, si es necesario), implemente la extensión como se describe en Procedimiento para registrar manualmente extensiones de PerformancePoint Services.

Vea también