Créer des fournisseurs de sources de données tabulaires pour PerformancePoint Services dans SharePoint

Découvrez comment créer le composant fournisseur de source de données dans une extension de source de données tabulaire personnalisée pour PerformancePoint Services.

Quels sont les fournisseurs de sources de données personnalisés pour PerformancePoint Services ?

Fournisseurs de sources de données se connecter à une source de données, accéder à ses données et les résultats de la requête puis revenez. PerformancePoint Services utilise des fournisseurs de sources de données tabulaires pour accéder aux données à partir de feuilles de calcul Excel et Excel Services, les listes SharePoint et les tables de Microsoft SQL Server. Vous pouvez créer un fournisseur de source de données personnalisé pour utiliser des données à partir d'une source de données tabulaires qui n'est pas pris en charge par PerformancePoint Services.

La fonction principale d'un fournisseur de source de données tabulaires consiste à créer et remplir une table de données avec des données à partir de la source de données. Il crée également des mappages de colonnes pour définir le type de données contenu dans chaque colonne (fait, dimension ou dimension de temps). Cela s'applique à la structure de base multidimensionnelle aux données tabulaires.

Les procédures et les exemples de code dans cette rubrique sont basées sur la classe WSTabularDataSourceProvider à partir de l' exemple d'objets personnalisés. Le fournisseur récupère les cotations boursières à partir d'un service web externe des symboles boursiers spécifiés. Il stocke les données de cotations boursières historique dans un fichier de cache, qui permet les données à être fractionnée par heure. Pour obtenir le code complet de la classe, voir Exemple de code : Créer un fournisseur de source de données pour les sources de données tabulaires PerformancePoint Services personnalisées dans SharePoint.

Nous vous recommandons d'utiliser l'exemple de fournisseur de source de données en tant que modèle. L'exemple montre comment appeler des objets dans l'API PerformancePoint Services et illustre les meilleures pratiques pour le développement de PerformancePoint Services.

Créer des fournisseurs de sources de données pour personnalisé PerformancePoint Services des sources de données tabulaires

  1. Install PerformancePoint Services, or copy the DLLs that your extension uses (listed in step 3) to your computer. Pour obtenir des instructions, consultez DLL avec des bibliothèques de classes.

  2. Dans Visual Studio, créez une bibliothèque de classes C#. Si vous avez déjà créé une bibliothèque de classes pour votre extension, ajoutez une nouvelle classe C#.

    Vous devez signer votre DLL en utilisant un nom fort. Par ailleurs, assurez-vous que tous les assemblys référencés par votre DLL ont des noms forts. Pour plus d’informations sur la signature d’un assembly avec un nom fort et sur la création d’une paire de clés publique/privée, consultez Guide pratique pour créer une paire de clés publique/privée.

  3. Ajoutez la suivante PerformancePoint Services DLL en tant que références d'assembly au projet :

  • Microsoft.PerformancePoint.Scorecards.Client.dll

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

    L'exemple de fournisseur de source de données contient également des références d'assembly à System.Core.dll, System.ServiceModel.dll, System.Web.dll, System.Web.Services.dll et System.Xml.Linq.dll. Selon la fonctionnalité de votre extension, d'autres références de projet peuvent être requises.

  1. Ajoutez une référence de service nommée StockQuotes qui référence le service Web situé à l'adresse http://www.webservicex.net/stockquote.asmx. Il s'agit du service Web qui fournit les cotations boursières pour l'exemple de source de données.

  2. Ajoutez les classes BasicTabularDataSourceProvider et SampleDSCacheHandler de l'exemple à votre projet. BasicTabularDataSourceProvider hérite de la classe TabularDataSourceProvider , qui est la classe de base pour les fournisseurs de sources de données tabulaires.

    L’exemple de source de données utilise également la classe comme conteneur pour les méthodes abstraites remplacées que TabularDataSourceProvider n’implémente pas ( GetDatabaseNames(),GetCubeNames() , GetCubeNameInfos() , GetCubeMetaData et Validate() ).

  3. Dans votre classe de fournisseur, ajoutez des directives using pour les espaces de noms PerformancePoint Services suivantes :

  1. Hériter de la classe BasicTabularDataSourceProvider.

  2. Déclarez les variables et définissez les propriétés utilisées pour l'analyse, le stockage et la récupération des symboles boursiers, l'emplacement du fichier cache et l'URI du serveur proxy.

  3. Remplacez la propriété IsConnectionStringSecure . Cette propriété n'est pas utilisée par PerformancePoint Services, mais elle est destinée aux applications personnalisées à utiliser (facultatif) pour déterminer si une chaîne de connexion expose des informations qui peuvent poser un problème de sécurité.

    Retournez true si votre extension stocke des informations sensibles, comme un nom d'utilisateur ou un mot de passe, dans la chaîne de connexion pour votre source de données. Retournez false si elle ne stocke pas d'informations sensibles ou si votre source de données n'utilise pas de chaîne de connexion.

  4. Remplacez la méthode GetId() pour retourner l’identificateur unique de votre fournisseur. GetId() doit retourner la même chaîne que l'attribut key qui est enregistrée dans le fichier web.config de PerformancePoint Services pour le fournisseur de source de données personnalisée.

  5. Remplacez la méthode SetDataSource pour définir des mappages de colonnes. SetDataSource appelle la méthode CreateDataColumnMappings pour définir les colonnes de source de données en tant que types Fact , Dimension et TimeDimension .

    SetDataSource récupère également les symboles boursiers, l'emplacement du fichier cache et l'adresse du serveur proxy à partir de la propriété CustomData de l'objet source de données personnalisé. Ces valeurs sont définies par les auteurs du tableau de bord dans l'exemple d'éditeur de source de données.

  6. Remplacez la méthode GetDataSet() pour créer un objet DataSet afin de stocker les données de la source de données. L'exemple de fournisseur de source de données utilise les méthodes FillResultsTable et GetLiveQuote pour remplir une table de données avec les données d'un service Web.

Exemple de code : Créer un fournisseur de source de données pour les sources de données tabulaires PerformancePoint Services personnalisées dans SharePoint

La classe dans l’exemple de code suivant crée un fournisseur de source de données tabulaires qui récupère les cotations boursières d’un service Web externe, puis transforme les données au format tabulaire.

Avant de pouvoir compiler cet exemple de code, vous devez configurer votre environnement de développement comme décrit dans Créer des fournisseurs de sources de données pour les sources de données tabulaires PerformancePoint Services personnalisées.


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
    }
}

Étapes suivantes

Après avoir créé un fournisseur de source de données et un éditeur de source de données (y compris son interface utilisateur, si nécessaire), déployez l’extension comme décrit dans Guide pratique pour inscrire manuellement PerformancePoint Services extensions.

Voir aussi