Datenzugriff in SharePoint: Business Data Connectivity Services

20. August 2012

Dies ist der siebte Teil einer Serie, die sich mit der Frage beschäftigt auf welche Arten Konfigurationen in Applikationen unter SharePoint gespeichert werden können. Es wird zuerst immer kurz die Methode vorgestellt, gefolgt von einem kurzen Beispiel und den Vor- und Nachteilen.

Eine vollständige Übersicht über bisherige und noch folgende Artikel ist hier zu finden.

Im heutigen Teil wird eine Möglichkeit vorgestellt auf Daten zuzugreifen ohne in der Applikation Kenntnisse über das Quellsystem zu besitzen.

Zu den vielfältigen Services, welche SharePoint anbietet, gehört der Nachfolger des Business Data Catalog (BDC) die Business Data Connectivity Services (BCS). Diese dienen dazu beliebige Fremdsysteme an SharePoint anzubinden und ermöglichen Daten aus Datenbanken, Web Services oder auch SAP in SharePoint verfügbar zu machen. Die BCS sind also weniger dazu geeignet z.B. einen ConnectionString zu speichern. Dafür aber umso besser um Daten direkt aus Fremdsystemen auszulesen.

Im Rahmen dieser Serie werden die Business Data Connectivity Services als einfacher Zugriff auf eine Konfigurationsdatenbank verwendet. Das bedeutet, wir legen eine für uns passende Entität in SharePoint an und konfigurieren diese für den Zugriff auf unsere Datenbank. Eine Applikation muss sich dann nicht mehr um die Verbindung kümmern. Es wird „nur“ die Entität angefragt und aus Sicht der Applikation stammen die Daten immer aus SharePoint.

Das hier aufgeführte Beispiel kann aber natürlich auch verwendet werden um unserer Applikation Daten aus einem beliebigen Fremdsystem zur Verfügung zu stellen.

BDC Model erstellen

Das Bindeglied zwischen SharePoint und Fremdsystemen sind die so genannten External Content Types. Es gibt zwei Möglichkeiten diese zu erstellen:

  • Anlegen des Modells in Visual Studio.
  • Modell mit SharePoint Designer erstellen.

Da die zweite Variante einfacher ist, gehen wir für unser Beispiel diesen Weg.

Zuerst erstellen wir eine Tabelle, auf welche wir dann später zugreifen wollen:

CREATE TABLE [dbo].[Konfiguration](

[Id] [int] IDENTITY(1,1) NOT NULL,

[Kategorie] [varchar](50) NOT NULL,

[Name] [varchar](50) NOT NULL,

[Wert] [varchar](50) NULL

) ON [PRIMARY]

Als nächstes starten wir den SharePoint Designer und öffnen unsere Site:

701

Hier wählen wir „External Content Types“ (ECT) und klicken auf “New”:

702

Wir geben dem ECT einen Namen und wählen „External System“ um die Datenquelle zu definieren:

703

Im folgenden Dialog fügen wir eine neue Verbindung mit „Add Connection“ hinzu:

704

In dem aufgehendem Dialog wählen wir den passenden SQL-Server und konfigurieren die Verbindung zu unserer Datenbank. Die Verbindung kann auch über dem im letzten Teil vorgestellten Secure Store erfolgen. Dazu muss im Dialog nur der Name des Secure Stores angegeben werden. Dieser benötigt natürlich das Recht den Secure Store auszulesen:

705

Nach Klick auf “Ok”, legt der SharePoint Designer die Verbindung im Metadata Store an. Wir wählen nun unsere Konfigurationstabelle mit einem Rechtsklick aus, und wählen „Create All Operations“:

706

Dies startet einen Wizard in dem wir auf „Next“ klicken:

707

Im nächsten Fenster müssen wir eine eindeutige Id Spalte benennen. Ohne diese kann SharePoint nicht mit den Daten arbeiten:

708

Im letzten Dialogfenster können wir noch einen Filter definieren. Dieser ist für unser Beispiel jedoch unerheblich. Wir beenden also den Wizard mit Klick auf „Finish“:

709

Der SharePoint Designer erstellt nun alle CRUD Operationen:

710

Zum Abschluss wird der External Content Type gespeichert und die Definition im Metadata Store abgelegt. In der Central Administration sind diese unter “Application Management” -> “Manage service applications” -> “Business Data Connectivity Service” zu finden.

711

Zugriff auf BCS

Zum Arbeiten mit den BCS benötigen wir zuerst einmal ein einfaches Datenobjekt:

public class Konfiguration

{

public int Id { get; set; }

public string Name { get; set; }

public string Kategorie { get; set; }

public string Wert { get; set; }

}

Als nächstes benötigen wir ein Repository, mit dem Einträge aus der Tabelle ausgelesen und geändert werden können. Dieses kommuniziert mit den BCS:

[DataObject]

public class KonfigurationRepository

{

private const string LobInstanceName = "Datenbank Beispiel";

private const string EntityName = "BeispielECT";

private const string EntityNameSpace = "http://spdev/personal/markus";

 

[DataObjectMethod(DataObjectMethodType.Select, true)]

public List<Konfiguration> Select()

{

var list = new List<Konfiguration>();

using (new SPServiceContextScope(SPServiceContext.GetContext(SPContext.Current.Site)))

{

// BCS Service ansprechen

var service = SPFarm.Local.Services.GetValue<BdcService>();

// Metadata Store für BCS Service ermitteln

var catalog = service.GetDatabaseBackedMetadataCatalog(SPServiceContext.Current);

// External Content Type definieren

var entity = catalog.GetEntity(EntityNameSpace, EntityName);

// LOB System laden

var instances = entity.GetLobSystem().GetLobSystemInstances();

var lobSysteminstance = instances[LobInstanceName];

// Read Methode definieren

var method = entity.GetMethodInstance("Read List", MethodInstanceType.Finder);

// Items abfragen

var items = entity.FindFiltered(method.GetFilters(), lobSysteminstance);

while (items.MoveNext())

{

if (items.Current != null)

{

// BCS Objekt auf Datenobjekt mappen

list.Add(new Konfiguration()

{

Id = (int)items.Current["Id"],

Name = items.Current["Name"].ToString(),

Kategorie = items.Current["Kategorie"].ToString(),

Wert = items.Current["Wert"].ToString()

});

}

}

}

return list;

}

 

[DataObjectMethod(DataObjectMethodType.Update, true)]

public void Update(Konfiguration neueKonfig)

{

using (new SPServiceContextScope(SPServiceContext.GetContext(SPContext.Current.Site)))

{

// BCS Service ansprechen

var service = SPFarm.Local.Services.GetValue<BdcService>();

// Metadata Store für BCS Service ermitteln

var catalog = service.GetDatabaseBackedMetadataCatalog(SPServiceContext.Current);

// External Content Type definieren

var entity = catalog.GetEntity(EntityNameSpace, EntityName);

// LOB System laden

var instances = entity.GetLobSystem().GetLobSystemInstances();

var lobSysteminstance = instances[LobInstanceName];

// Id für Abfrage definieren 

var identity = new Identity(neueKonfig.Id);

// Objekt laden, Werte setzen und updaten.

var instance = entity.FindSpecific(identity, lobSysteminstance);

instance["Name"] = neueKonfig.Name;

instance["Wert"] = neueKonfig.Wert;

instance.Update();

}

}

}

Als letztes erstellen wir ein WebPart mit einem GridView und einer ObjectDataSource um die Daten anzeigen und bearbeiten zu können:

public class WebPartMitBCS : WebPart

{

protected override void CreateChildControls()

{

var dataSource = new ObjectDataSource

{

ID = "Source",

UpdateMethod = "Update",

SelectMethod = "Select",

TypeName = typeof(KonfigurationRepository).AssemblyQualifiedName,

DataObjectTypeName = typeof(Konfiguration).AssemblyQualifiedName

};

 

 

var gridView = new GridView

{

ID = "GridViewKonfig",

AutoGenerateEditButton = true,

AutoGenerateColumns = true,

DataSourceID = dataSource.ID

};

 

Controls.Add(dataSource);

Controls.Add(gridView);

 

// DataBind wird sonst mehrfach aufgerufen

if (!Page.IsPostBack)

{

gridView.DataBind();

}

}

}

Fazit

Zum Abschluss wieder die Vor- und Nachteile der Business Data Connectivity Services:

Vorteile:

  • Sicherheit

    Rechte können sehr granular in SharePoint verwaltet werden.

  • Scope

    Es können beliebige Datenquellen angebunden werden. SharePoint kümmert sich hierbei um den Datenzugriff

Nachteile:

  • Administration

    Es gibt keine mitgelieferte Oberfläche zum Verwalten der Werte.

  • Implementierung

    Umsetzung ist sehr aufwendig im Vergleich zu anderen Methoden.

  • Wartbarkeit

    External Content Types müssen separat erstellt und verteilt werden