Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden

Erstellung einer Konfigurationsdatei für einen Business Data Catalog

Eine Konfigurationsdatei für Business Data Catalogs ist eine XML-Datei, die dem Schema bdcmetadata.xsd ent­spricht. Zum Binden der XSD-Datei an die neue XML-Datei gibt es meh­rere Möglichkeiten:

Wenn man die Datei im Visual Studio ent­wi­ckeln möchte kopiert man am bes­ten die Datei bdcmetadata.xsd in die Visual Studio 2005 Schema Library. Die Datei ist im Order Program Files\Microsoft Office Servers\12.0\Bin zu fin­den und sollte in den Ordner Program Files\Microsoft Visual Studio 8\Xml\Schemas kopiert wer­den. Alternativ kann die Datei auch direkt von den Microsoft-Servern her­un­ter­ge­la­den wer­den (http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog/BDCMetadata.xsd) oder die XML-Datei an die Datei unter der ange­ge­be­nen URL gebun­den werden.

Im Visual Studio wird nun eine neue XML-Datei gene­riert. In den Dokumenteigenschaften wird die XML-Datei an das Schema bdcmetadata.xsd gebunden.

Zudem sollte das Schema auch als Attribut des LobSystem-Knotens ange­ge­ben wer­den. Hier ist es dann sinn­voll, gleich die Entsprechung auf den Microsoft-Servern zu verwenden. 

<LobSystem
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog BDCMetadata.xsd"
    Type="Database"
    Version="1.0.0.0"
    Name="DocumentArchive"
    xmlns="http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog">
</LobSystem>

Der im Attribut Name ange­ge­bene Name wird dann spä­ter im Sharepoint als Name der Applikation verwendet.

Als nächs­tes müs­sen die Verbindungseigenschaften fest­ge­legt wer­den. Hierzu legt man als Childnode von LobSystem einen Knoten LobSystemInstances an, der die Verbindungseinstellungen zur Datenbank enthält. 

<LobSystemInstances>
    <LobSystemInstance Name="ArchiveDatabase">
        <Properties>
            <Property Name="AuthenticationMode" Type="System.String">PassThrough</Property>
            <Property Name="DatabaseAccessProvider" Type="System.String">SqlServer</Property>
            <Property Name="RdbConnection Data Source" Type="System.String">DEV-EV-01</Property>
            <!-- The name of your ser­ver hos­ting the database-->
            <Property Name="RdbConnection Initial Catalog" Type="System.String">Archive</Property>
            <!-- The name of the data­base. -->
            <Property Name="RdbConnection Integrated Security" Type="System.String">SSPI</Property>
        </Properties>
    </LobSystemInstance>
</LobSystemInstances>

Im Knoten LobSystem\Entities wer­den die ver­schie­de­nen Entitäten fest­ge­legt, die abruf­bar sind. In der Entität wird eine Methode defi­niert, die für das Abrufen der Daten ver­ant­wort­lich ist. 

<Entities>
    <Entity Name="Document">
        <Methods>
            <Method Name="GetDocuments">
                <Properties>
                    <!-- add pro­per­ties here -->
                </Properties>
                <Parameters>
                    <!-- add para­me­ters here -->
                </Parameters>
                <MethodInstances>
                    <!-- add method ins­tances here -->
                </MethodInstances>
            </Method>
        </Methods>
    </Entity>
</Entities>

Dabei bestimmt die Eigenschaft RdbCommandText das SQL-Statement zum Abrufen der Daten. Hierbei ist dar­auf zu ach­ten, dass Sonderzeichen wie „>“ und „<“ zu codie­ren sind (&lt; bzw. &gt;).

<Properties>
    <Property Name="RdbCommandText" Type="System.String">
        SELECT [ID]
        ,[OriginalPath]
        ,[OriginalFileName]
        ,[Size]
        FROM [dbo].[Documents]
        WHERE [ID] &gt; 0
    </Property>
    <Property Name="RdbCommandType" Type="System.Data.CommandType">Text</Property>
</Properties>

Unter dem Knoten Parameters der Methode ist nun der Rückgabetyp zu dekla­rie­ren. Bei Datenbankabfragen han­delt es sich hier um einen DataReader (= Collection), der DataRecords ent­hält. Unterhalb des DataRecords wer­den die ein­zel­nen Rückgabespalten deklariert.

<Parameters>
    <Parameter Direction="Return"
Name="Documents">
        <TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="DocumentDataReader">
             <TypeDescriptors>
                <TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="DocumentDataRecord">
                    <TypeDescriptors>
                        <TypeDescriptor TypeName="System.Int32" Name="ID"/>
                        <TypeDescriptor TypeName="System.String" Name="OriginalPath"/>
                        <TypeDescriptor TypeName="System.String" Name="OriginalFileName"/>
                        <TypeDescriptor TypeName="System.Int32" Name="Size"/>
                    </TypeDescriptors>
                </TypeDescriptor>
            </TypeDescriptors>
        </TypeDescriptor>
    </Parameter>
</Parameters>

Für die ein­zel­nen Spalten kön­nen jetzt noch Anzeigenamen dekla­riert wer­den. Hierzu dekla­riert man unter­halb des TypeDescriptors für die jewei­lige Spalte jeweils einen LocalizedDisplayName für die gewünschte Sprache.

<TypeDescriptor TypeName="System.String" Name="OriginalPath">
    <LocalizedDisplayNames>
        <LocalizedDisplayName LCID="1033">Path to File</LocalizedDisplayName>
        <LocalizedDisplayName LCID="1031">Pfad zur Datei</LocalizedDisplayName>
    </LocalizedDisplayNames>
</TypeDescriptor>

Nun wird noch ein Knoten MethodInstances erzeugt, der den Finder dekla­riert. Dieser ist not­wen­dig, damit Instanzen der Entities erzeugt wer­den kön­nen. Sharepoint benutzt die Finder-Methode, um alle Instanzen der Entitiy abzu­ru­fen und die SpecificFinder-Methode um bestimmte Entities abzu­ru­fen. Bei der Deklaration bezieht man sich auf die eben dekla­rier­ten Rückgabewerte. 

<MethodInstances>
    <MethodInstance Name="DocumentFinderInstance" Type="Finder" ReturnParameterName="Documents" ReturnTypeDescriptorName="DocumentDataReader"/>
    <MethodInstance Name="DocumentSpecificFinderInstance" Type="SpecificFinder" ReturnParameterName="Documents" ReturnTypeDescriptorName="DocumentDataReader"/>
</MethodInstances>

Damit der SpecificFinder die Datensätze auch fin­den kann, muss noch der Identifier der Entity dekla­riert wer­den. Der Identifier ist in der Regel der Primärschlüssel der Tabelle. 

<Identifiers>
    <Identifier Name="ID" TypeName="System.Int32" />
</Identifiers>

Dem ent­spre­chen­den Feld im Resultset wird nun noch die Eigenschaft IdentifierName zuge­wie­sen und damit eine Referenz erzeugt. Damit sieht nun der TypeDescriptor-Tag wie folgt aus: 

<TypeDescriptor TypeName="System.Int32" IdentifierName="DocumentID" Name="ID">
    <LocalizedDisplayNames>
        <LocalizedDisplayName LCID="1033">Document ID</LocalizedDisplayName>
        <LocalizedDisplayName LCID="1031">Dokument Nummer</LocalizedDisplayName>
    </LocalizedDisplayNames>
</TypeDescriptor>

Wenn man die Konfigurationsdatei für die Applikation nun mal hoch­lädt kann man sich das Ergebnis in einer Business Data List anschauen. 

image 

Die Elemente sind schon sortier- und filterbar. 

Um die Filtermöglichkeiten als Eingabefelder frei­zu­schal­ten sind noch einige Änderungen an der Konfiguration notwendig. 

Im Beispiel soll eine Like-Suche auf den Dokument-Namen ermög­licht wer­den. Zunächst wird der SQL-Command ange­passt, so dass hier Parameter ange­nom­men werden. 

<Property Name="RdbCommandText" Type="System.String">
    SELECT [ID]
    ,[OriginalPath]
    ,[OriginalFileName]
    ,[Size]
    FROM [dbo].[Documents]
    WHERE [OriginalFileName] LIKE @Name
</Property>

Im Anschluss daran muss das Wildcard-Zeichen des Backends fest­ge­legt wer­den. Das Frontend-Wildcard-Zeichen „*“ wird durch die­ses Zeichen ersetzt. Im SQL-Server ist das „%“. Die ent­spre­chende Einstellung nimmt man in den Eigenschaften des LobSystems vor. 

<Properties>
    <Property Name="WildcardCharacter" Type="System.String">%</Property>
</Proper
ties>

Nun erfol­gen noch einige Anpassungen an der Methode, die die Daten liest. Zunächst wird der im SQL-Statement ver­wen­dete Parameter als Eingabeparameter bekannt gege­ben. Hierzu fügt man einen wei­te­ren Parameter-Tag im Parameters-Tag der Methode ein. Für jeden Finder wird ein Standardwert für die­sen Parameter festgelegt. 

<Parameter Direction="In" Name="@Name">
    <TypeDescriptor TypeName="System.String" AssociatedFilter="Name" Name="Name">
        <DefaultValues>
            <DefaultValue MethodInstanceName="DocumentFinderInstance" Type="System.String">%</DefaultValue>
            <DefaultValue MethodInstanceName="DocumentSpecificFinderInstance" Type="System.String">%</DefaultValue>
        </DefaultValues>
    </TypeDescriptor>
</Parameter>

Der Parameter bezieht sich auf den Filter mit dem Namen „Name“, der bis­her noch nicht exis­tiert. Die Filter wer­den im Unterknoten FilterDescriptors der Methode definiert. 

<FilterDescriptors>
    <FilterDescriptor Type="Wildcard" Name="Name">
        <Properties>
            <Property Name="UsedForDisambiguation" Type="System.Boolean">true</Property>
        </Properties>
    </FilterDescriptor>
</FilterDescriptors>

Als Ergebnis erhält man bei der Anzeige des Webparts jetzt eine Eingabemaske in der man nach dem eben defi­nier­ten Filter fil­tern kann. 

image

2. Oktober 2007

Pin It on Pinterest