Freigeben über


Erstellen von Anbietern für tabellarische Datenquellen für PerformancePoint-Dienste in SharePoint

In diesem Artikel erfahren Sie, wie die Datenquellenanbieter-Komponente in einer benutzerdefinierten Datenquellenerweiterung in Tabellenform für PerformancePoint-Dienste erstellt wird.

Was sind benutzerdefinierte Datenquellenanbieter für PerformancePoint-Dienste ?

Datenquellenanbieter Verbinden mit einer Datenquelle, Zugriff auf seine Daten und dann Abfrageergebnisse. PerformancePoint-Dienste verwendet Anbietern für tabellarische Datenquellen, um Daten in Arbeitsblättern Excel und Excel Services, SharePoint-Listen und Tabellen Microsoft SQL Server zugreifen. Sie können Erstellen einer benutzerdefinierten Datenquellenanbieter, um Daten aus einer tabellarischen Datenquelle verwenden, die von PerformancePoint-Dienste nicht unterstützt wird.

Die Hauptfunktion der eine tabellarische Datenquellenanbieter ist zu erstellen, und füllen eine Datentabelle mit Daten aus der Datenquelle. Darüber hinaus erstellt spaltenzuordnungen, um den Typ der Daten definieren, dass jeder Spalte (Fakten-, Dimensions- oder Zeitdimension) enthält. Dies gilt eine multidimensionale grundlegende Struktur für die Tabellendaten.

Bei den Verfahren und Codebeispiele in diesem Thema basieren auf der WSTabularDataSourceProvider -Klasse aus der benutzerdefinierten Objekte (Beispiel). Der Anbieter Bestandsquoten aus eines externen Webdiensts für die angegebene Aktiensymbole abgerufen. Speichert zurückliegenden Aktienkursdaten in eine Cachedatei, die die Daten zum Zeitpunkt Slices aufgeteilt werden kann. Den vollständigen Code für die -Klasse finden Sie unter Codebeispiel: Erstellen eines Datenquellenanbieters für benutzerdefinierte PerformancePoint-Dienste tabellarischen Datenquellen in SharePoint.

Es wird empfohlen, dass Sie den Datenquellenanbieter Beispiel als Vorlage verwenden. Das Beispiel zeigt, wie Objekte in der PerformancePoint-Dienste-API-aufrufen und bewährte Methoden für die Entwicklung von PerformancePoint-Dienste veranschaulicht.

Erstellen von Datenquellenanbieter für benutzerdefinierte PerformancePoint-Dienste tabellarische Datenquellen

  1. Installieren Sie PerformancePoint-Dienste, oder kopieren Sie die DLLs, die die Erweiterung verwendet (siehe Schritt 3) auf Ihrem Computer. Anweisungen finden Sie unter DLLs mit Klassenbibliotheken.

  2. Erstellen Sie in Visual Studio eine C#-Klassenbibliothek. Sollten Sie bereits eine Klassenbibliothek für die Erweiterung erstellt haben, fügen Sie eine neue C#-Klasse hinzu.

    Sie müssen die DLL mit einem starken Namen signieren. Stellen Sie außerdem sicher, dass alle Assemblys, auf die von der DLL verwiesen wird, ebenfalls starke Namen haben. Informationen zum Signieren einer Assembly mit einem starken Namen und zum Erstellen eines öffentlichen/privaten Schlüsselpaars finden Sie unter Vorgehensweise: Erstellen eines öffentlichen/privaten Schlüsselpaars.

  3. Fügen Sie die folgenden PerformancePoint-Dienste DLLs als Assemblyverweise zum Projekt hinzu:

  • Microsoft.PerformancePoint.Scorecards.Client.dll

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

    The sample data source provider also contains assembly references to System.Core.dll, System.ServiceModel.dll, System.Web.dll, System.Web.Services.dll, and System.Xml.Linq.dll. Depending on your extension's functionality, other project references may be required.

  1. Fügen Sie einen Dienstverweis mit dem Namen StockQuotes hinzu, mit dem auf den Webdienst mit der Adresse http://www.webservicex.net/stockquote.asmx verwiesen wird. Dieser Webdienst liefert Aktienkurse für die Beispieldatenquelle.

  2. Fügen Sie dem Projekt die Klassen BasicTabularDataSourceProvider und SampleDSCacheHandler aus dem Beispiel hinzu. BasicTabularDataSourceProvider erbt von der TabularDataSourceProvider -Klasse, die eine Basisklasse für Anbieter für tabellarische Datenquellen ist.

    Die Beispieldatenquelle verwendet die -Klasse auch als Container für die überschriebenen abstrakten Methoden, die TabularDataSourceProvider nicht implementiert ( GetDatabaseNames(),GetCubeNames() , GetCubeNameInfos() , GetCubeMetaData und Validate() ).

  3. Fügen Sie in der Anbieterklasse using Direktiven für die folgenden PerformancePoint-Dienste-Namespaces hinzu:

  1. Erben Sie von der BasicTabularDataSourceProvider-Klasse.

  2. Deklarieren Sie Variablen, und definieren Sie Eigenschaften, mit denen Sie Aktiensymbole, den Speicherort für die Cachedatei sowie den URI des Proxyservers analysieren, speichern und abrufen.

  3. Überschreiben Sie die IsConnectionStringSecure-Eigenschaft . Diese Eigenschaft wird nicht vom PerformancePoint-Dienste verwendet, aber es ist für die benutzerdefinierte Anwendungen, optional verwenden, um festzustellen, ob eine Verbindungszeichenfolge-Informationen verfügbar macht, die ein Sicherheitsrisiko vorgesehen.

    Es wird true zurückgegeben, wenn von der Erweiterung vertrauliche Informationen (z. B. ein Benutzername oder Kennwort) in der Verbindungszeichenfolge für Ihre Datenquelle gespeichert werden. false wird zurückgegeben, wenn keine vertraulichen Informationen gespeichert werden oder wenn von der Datenquelle keine Verbindungszeichenfolge verwendet wird.

  4. Überschreiben Sie die GetId() -Methode, um den eindeutigen Bezeichner für Ihren Anbieter zurückzugeben. GetId() muss die gleiche Zeichenfolge wie das Attribut key zurückgeben, die in der PerformancePoint-Dienste web.config-Datei für den benutzerdefinierten Datenquellenanbieter registriert ist.

  5. Überschreiben Sie die SetDataSource-Methode , um Spaltenzuordnungen zu definieren. SetDataSource ruft die CreateDataColumnMappings-Methode auf, um Datenquellenspalten vom Typ Fact , Dimension und TimeDimension zu definieren.

    Mit SetDataSource werden auch die Aktiensymbole, der Speicherort für die Cachedatei und die Proxyserveradresse aus der CustomData -Eigenschaft des benutzerdefinierten Datenquellenobjekts abgerufen. Diese Werte werden von Dashboardautoren im Beispiel-Datenquellen-Editor definiert.

  6. Überschreiben Sie die GetDataSet()- Methode, um ein DataSet-Objekt zum Speichern der Daten aus der Datenquelle zu erstellen. Der Beispiel-Datenquellenanbieter verwendet die Methoden FillResultsTable und GetLiveQuote zum Auffüllen einer Datentabelle mit Daten eines Webdiensts.

Codebeispiel: Erstellen eines Datenquellenanbieters für benutzerdefinierte tabellarische PerformancePoint-Dienste-Datenquellen in SharePoint

Mithilfe der Klasse im folgenden Codebeispiel wird ein Anbieter für tabellarische Datenquellen erstellt, mit dem Aktienkurse von einem externen Webdienst abgerufen und die Daten anschließend in ein tabellarisches Format transformiert werden.

Bevor Sie dieses Codebeispiel kompilieren können, müssen Sie Ihre Entwicklungsumgebung wie unter Erstellen von Datenquellenanbietern für benutzerdefinierte PerformancePoint-Dienste tabellarischen Datenquellen beschrieben konfigurieren.


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

Nächste Schritte

Nachdem Sie einen Datenquellenanbieter und einen Datenquellen-Editor (einschließlich seiner Benutzeroberfläche, falls erforderlich) erstellt haben, stellen Sie die Erweiterung wie unter Vorgehensweise: Manuelles Registrieren von PerformancePoint-Dienste-Erweiterungen beschrieben bereit.

Siehe auch