Dokument-Parameter – Datasources
Allgemein
Mit den DataSources kann eine Datenbankabfrage in den Dokument-Parameter eingeschleust werden. Diese Abfragen werden beim Öffnen des Dokument-Parameter-Dialoges, je nach definiertem "Loadbehavior" (siehe Selector), aufgerufen. Die Daten aus der Abfrage können dann über das Mapping des Selectors auf DataNodes gemappt werden.
Die Grundstruktur für eine DataSource-Anbindung sieht folgendermassen aus:
<DataSources>
<DataSource>
<ConnectionProvider />
<ConnectionString />
<Selector LoadBehavior="Value">
<Query />
<Result>
<!-- Pro Selektor kann entweder ein SingleMap oder ein CollectionMap definiert werden. -->
<SingleMap>
<Map Source="ColumnName1" Target="CustomDataNode1" />
<Map Source="ColumnName2" Target="CustomDataNode2" />
</SingleMap>
<CollectionMap id="IdOfCollection">
</CollectionMap>
</Result>
</Selector>
</DataSource>
</DataSources>
DataSource
Der DataSourceNode kann verschieden Typen annehmen. Der Name ist im XML identisch mit den hier aufgelisteten DataSource-Typen.
Attribute und Elemente für jeden Typ DataSource
Name | Beschreibung |
---|---|
Id (Optional, Attribut) | Gibt der DataSource eine eindeutige Id. |
ConnectionProvider (Zwingend, Element) | Definiert den ConnectionProvider für den entsprechenden Datenbank-Typen. Über diesen Provider wird die Verbindung zur Datebank hergestellt. Übersicht über die ConnectionProvider des .NET Frameworks |
ConnectionString (Zwingend, Element) | Der ConnectionString bietet die nötigen Informationen zum Herstellen der Verbindung auf die Datenbank. Jede Datenbank definiert ihr eigenes Format für den ConnectionString. |
Selector (Zwingend, Element) | Definiert die Datenbankabfrage (Query) und das entsprechende Mapping auf die DataNodes. |
Datenbanktypen und ihre typenspezifische Attribute
Typ | Attribute |
---|---|
SqlDataSource | SafeQuery Wenn der Wert auf "true" gesetzt ist (Standard), dann werden etwaige Parameter (siehe Selector → Query) in der Query nicht mit den aktuellen Werten ersetzt. Es wird hingegen eine Parameter-Liste mit dem Key-Value-Paar an die Datenbank gesendet. Diese ersetzt dann die Werte in der Query. Dadurch entsteht eine erhöhte Sicherheit betreffend SQL-Injection. |
Selector
Der Selector definiert den Ausführzeitpunkt, die auszuführende Datenbankabfrage und das enstprechende Mapping auf die DataNodes. Eine DataSource kann beliebig viele Selectoren enthalten.
Name | Beschreibung |
---|---|
Id (Optional, Attribut) | Innerhalb einer DataSource eineindeutig |
LoadBehavior (Zwingend, Attribut) | Definiert, bei welcher Art von Aufruf des Dokument-Parameters die Abfrage ausgelöst werden soll. Die möglichen LoadBehaviors sind: OnlyOnce: bei erster Initierung des Dokument-Parameters Always: immer wenn der Dokument-Parameter-Dialog aufgerufen wird (auch wenn er aus dem generierten Dokument heraus geöffnet wird). |
Query (Zwingend, Element) | Die Abfrage, die auf der Datenbank ausgeführt wird. Mit {} können Platzhalter eingesetzt werden, und so z. B. auf den Wert eines DataNodes verweisen → {DocParam.ValueToInject}. Wenn Platzhalter eingesetzt werden, muss beachtet werden, dass die CustomElements, die angesprochen werden, einen validen Standardwert haben. Sonst kann es sein, dass die Abfrage fehlschlägt. Dies kann dazu führen, dass das Öffnen des Dokument-Parameter-Dialoges fehlschlägt. Wenn in der Query ein < oder ein > verwendet wird, dann muss diese in einem <![CDATA[InsertQueryHere]]> -Tag stehen. |
Result (Zwingend, Element) | Das Result-Element des Selectors enthält die Information, wie die Werte aus der Datenbank auf die CustomElements gemappt werden sollen. Dabei wird zwischen zwei Typen unterscheiden: CollectionMap und SingleMap. Die genaue Anwendung ist aufgrund der Komplexität unter dieser Tabelle aufgeführt. |
Mapping
Um das Mapping zu erklären, wird die folgende Grundkonfiguration verwendet:
<Configuration>
<CustomContentSection xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="{[DocParam.Config.WindowName]}" WindowHeight="450" WindowWidth="{[DocParam.Config.WindowWidth]}">
<DataNodes>
{[DocParam.EnableDocParamButton]}
<CustomDataNode xsi:type="TextNode" Id="DocParam.Name" LCID="1042" />
<CustomDataNode xsi:type="TextNode" Id="DocParam.Vorname" LCID="1042" />
<CustomDataNode xsi:type="TextNode" Id="DocParam.Funktion" LCID="1042" />
<CustomDataNode xsi:type="TextNode" Id="DocParam.Lohn" LCID="1042" />
</DataNodes>
</CustomContentSection>
<Views>
<DataNodes>
<Collection Id="MAList"></Collection>
</DataNodes>
<View Id="main" Label="{[DocParam.LabelMainView]}">
<!-- Hier erfolgt die View-Konfiguration -->
</View>
</Views>
<DataSources>
<SqlDataSource>
<ConnectionProvider>System.Data.SqlClient</ConnectionProvider>
<ConnectionString>Data Source=SomeServer; DataBase=SomeDatabase; Integrated Security=true; </ConnectionString>
<SafeQuery>true</SafeQuery>
<Selector LoadBehavior="OnlyOnce">
<Query><![CDATA[SELECT Name, Vorname, Funktion, Lohn FROM tblMitarbeiter WHERE Name LIKE '%something%' AND Lohn > 20000]]> </Query>
<Result>
<!-- Hier erfolgt die Konfiguration des Mappings -->
</Result>
</Selector>
</SqlDataSource>
</DataSources>
</Configuration>
SingleMap
Mit dem SingleMap können einzelne Spalten aus der Datenbankabfrage auf einen DataNode gemappt werden. Das Ziel ist nun, das Resultat aus der Datenbankabfrage in die konfigurierten DataNodes abzufüllen. Für das SingleMap sieht die Konfiguration innerhalb des <Result></Result>
{:.language-xml} folgendermassen aus:
<Result>
<SingleMap>
<Map Source="Name" Target="DocParam.Name" />
<Map Source="Vorname" Target="DocParam.Vorname" />
<Map Source="Funktion" Target="DocParam.Funktion" />
<Map Source="Lohn" Target="DocParam.Lohn" />
</SingleMap>
</Result>
Das Source
-Attribut enthält den Namen der Spalte aus der Datenbankabfrage, aus welcher der Wert ausgelesen werden soll. Das Target
-Attribut enthält den Namen des DataNodes, auf welchen der Wert geschrieben werden soll. Für die entsprechenden DataNodes kann dann auch ein View-Element erstellt werden, um den Wert darzustellen.
Wird mit einem SingleMap auf einen TextNode gemapt, dann wird jeweils nur der erste Eintrag der Datenbankabfrage beachtet, alle anderen Einträge werden ignoriert. Wird hingegen auf eine ComboBox gemappt, werden sämtliche Werte aus der Spalte in die ComboBox eingfügt.
CollectionMap
Mit der CollectionMap kann eine Liste, die aus der Datenbankabfrage zurückgegeben wird, auf eine Collection geschrieben werden. Die Collection wird mit den entsprechenden Elementen befüllt. Auf diese Collection kann dann über eine ComboBox zugegriffen werden. Für das CollectionMap sieht die Konfiguration innerhalb des <Result></Result>
folgendermassen aus:
<Result>
<CollectionMap Id="MAList" />
</Result>
Die ColletionMap braucht nur die Id der entsprechenden Collection auf die die Werte geschrieben werden sollen. Diese Collection ist zwingend in den ViewDataNodes zu definieren. Die Collection wird dann folgendermassen befüllt:
<Collection Id="MaList">
<Element>
<Text Id="Name">Muster</Text>
<Text Id="Vorname">Max</Text>
<Text Id="Funktion">Sachbearbeiter Administration</Text>
<Text Id="Lohn">5100</Text>
</Element>
<Element>
.
.
</Element>
.
.
</Collection>
Die Id der Text-Elemente innerhalb eines Elementes der Collection enthalten den Namen der Spalte aus der Datenbankabfrage, und entsprechend den Wert, welcher der ausgewertete Eintrag in der entsprechenden Spalte der Abfrage enthält. Auf diese Collection kann dann über eine ComboBox folgendermassen zugegriffen werden:
<ComboBox Id="MAList" CollectionLabelMember="Vorname" CollectionPlaceholder="Select">
<CollectionSelectionMap Source="Name" Target="DocParam.Name"></CollectionSelectionMap>
<CollectionSelectionMap Source="Vorname" Target="DocParam.Vorname"></CollectionSelectionMap>
<CollectionSelectionMap Source="Funktion" Target="DocParam.Funktion"></CollectionSelectionMap>
<CollectionSelectionMap Source="Lohn" Target="DocParam.Lohn"></CollectionSelectionMap>
</ComboBox>
Der Wert, der in der ComboBox angezeigt wird, wird im CollectionLabelMember definiert, hier ist es beispielsweise der Vorname. Wird ein Wert in der ComboBox ausgewählt, werden die entsprechenden Werte aus der Collection (Source) in die im Mapping definierten DataNodes (Target) geschrieben. Hier ist wieder darauf zu achten, dass die Source der Id des Textes in der Collection, also dem Namen der Spalte aus der Datenbankabfrage, entspricht. Dasselbe gilt für das Target des entsprechenden DataNodes.