D365CE — Dataverse / Customer Engagement
Der D365CE-Konnektor verbindet die DataBridge mit Microsoft Dataverse und Dynamics 365 Customer Engagement über das offizielle Dataverse SDK. Er nutzt die Change Tracking API für eine lückenlose Erkennung aller Änderungen.
| Eigenschaft | Wert |
|---|---|
| Lesen | ✅ unterstützt |
| Schreiben | ✅ unterstützt |
| Job-Filter | ✅ clientseitig nach dem Abruf |
| Status | Freigegeben |
| Getestete Mindestversion | Dataverse / D365CE v9.1 |
Die Mindestversion beschreibt den getesteten Stand; eine Versionsprüfung findet im Code nicht statt.
Voraussetzung: Change Tracking aktivieren
Für alle Dataverse-Tabellen, die als Quelle genutzt werden, muss Change Tracking aktiviert sein. Ohne Change Tracking kann der Konnektor keine Differenzabfragen durchführen.
Aktivierung: Power Platform Admin Center → Umgebung → Tabellen → Tabelle auswählen → Eigenschaften → Änderungsnachverfolgung aktivieren ✅
Verbindungsparameter
{
"connectionstring": "<XRM-Connection-String>"
}
Beispiel (Client Secret Authentication):
AuthType=ClientSecret;Url=https://<org>.crm4.dynamics.com;ClientId=<id>;ClientSecret=<secret>
Die vollständige XRM-Connection-String-Referenz findet sich in der Microsoft-Dokumentation.
Zusätzlich stehen die universellen Parameter keyVaultUrl, maxPageSize, language und
httpClientTimeoutSeconds zur Verfügung — siehe
Verbindungen.
Tabellen- und Feldnamen
SourceTable / TargetTable
Logischer Entitätsname in Kleinbuchstaben — so wie er in den Dataverse-Metadaten steht.
| Entität | SourceTable |
|---|---|
| Account | account |
| Contact | contact |
| Custom Entity | wysa_bcsegment |
SourceField / TargetField
Logischer Attributname in Kleinbuchstaben.
| Attribut | SourceField |
|---|---|
| Account Name | name |
| Custom Field | wysa_bcsystemid |
Unterstützte TargetKey-Typen
| Typ | Beschreibung |
|---|---|
PrimaryKey | Dataverse GUID (Primärschlüssel der Entität) |
CustomKey | Benutzerdefinierter Schlüssel über ein oder mehrere Felder (Alternate Key) |
Filter | Suche über Feldwert-Kombination ohne expliziten Schlüssel |
Bei CustomKey werden Schlüsselteile vom Typ int32, guid und string unterstützt;
jeder andere Typ führt zum Abbruch (keytype … not yet supported for key …).
Leere Schlüsselteile werden übersprungen — bleibt danach kein Teil übrig, gilt der
Schlüssel als nicht auflösbar.
Ein KeyValue kann statt attributeName ein StaticValue enthalten; der Schlüsselteil
wird dann fest gesetzt und als Typ string behandelt.
Anders als bei D365BC und D365NAV kennt der CE-Konnektor
keinen TargetKey-Typ Id. Ein unbekannter oder falsch geschriebener KeyType löst
keinen Fehler aus, sondern nur eine Warnung im Log
(Undefined Key definition for InitiateEntityWithKey); der Schlüssel gilt anschließend
als nicht auflösbar.
Für die Fehlersuche bedeutet das: Ein Lookup, das dauerhaft leer bleibt, oder ein Upsert,
der scheinbar wirkungslos ist, kann schlicht an einem ungültigen KeyType liegen. Der
Hinweis erscheint ausschließlich als Warnung, nicht als Ausnahme.
Mehrere Ziel-Schlüssel mit Rangfolge (ab v2.1)
Statt eines einzelnen TargetKey lässt sich eine Liste TargetKeys angeben. Die
Schlüssel werden nach KeyRank aufsteigend geprüft; der erste Schlüssel, der im
Zielsystem einen Datensatz findet, gewinnt — alle weiteren werden übersprungen.
{
"Operations": [
{
"Name": "Lookup",
"Parameters": {
"TargetTable": "wysa_countryregion",
"TargetKeys": [
{
"KeyType": "CustomKey",
"KeyRank": 1,
"KeyName": "wysa_externalid",
"KeyValues": [
{ "keyName": "wysa_externalid", "attributeName": "externalId", "rank": 1 }
]
},
{
"KeyType": "CustomKey",
"KeyRank": 2,
"KeyName": "wysa_code",
"KeyValues": [
{ "keyName": "wysa_code", "attributeName": "countryRegionCode", "rank": 1 }
]
}
]
}
}
]
}
Bestehende Mappings mit einem einzelnen TargetKey funktionieren unverändert weiter.
SourceOperations
LookupValue
Liest einen Wert aus einem verknüpften Dataverse-Datensatz nach.
{
"Operations": [
{
"Name": "LookupValue",
"Parameters": {
"LookupType": "Attribute",
"SourceField": "wysa_countrycode",
"LookupTable": "wysa_country",
"LookupField": "wysa_name",
"UseCache": true
}
}
]
}
LookupType kennt zwei Werte. Nur der CE-Konnektor unterstützt beide:
| Wert | Wirkung |
|---|---|
Attribute | Der genannte LookupField-Wert wird aus dem verknüpften Datensatz gelesen |
Name | Der Anzeigename der Referenz wird direkt aus dem Quelldatensatz übernommen — ohne zusätzliche Abfrage |
Der CE-Konnektor löst benötigte Lookup-Werte vor der Verarbeitung eines Batches gebündelt auf und legt sie im Cache ab. Die IDs werden dazu in Blöcken zu je 1.000 Stück abgefragt, statt jeden Wert einzeln nachzuschlagen. Das beschleunigt die Verarbeitung großer Änderungsmengen spürbar.
Die Vorab-Auflösung greift nur bei UseCache: true. Ohne diese Option bleibt es bei
Einzelabfragen. Die Funktion ist dem CE-Konnektor vorbehalten — D365BC und D365NAV
verfügen nicht darüber.
ReadFromMessage
Liest Werte aus einer vorherigen Quellanfrage — nur in ResponseJobs. Verhalten wie beim D365BC-Konnektor.
ActivityParty
Liest ein Feld über eine ActivityParty-Beziehung. Wird für CE-Aktivitäten
(E-Mails, Aufgaben, Anrufe) verwendet, bei denen Teilnehmer über den
activityparty-Datensatz verknüpft sind.
{
"Operations": [
{
"Name": "ActivityParty",
"Parameters": {
"PartyParams": {
"TypeMask": 2,
"SourceField": "activityid",
"TargetField": "wysa_number",
"TargetTable": "contact"
}
}
}
]
}
TypeMask entspricht dem Dataverse-Feld participationtypemask und wird von der
DataBridge unverändert an die Abfrage durchgereicht. Die gültigen Werte gibt die
Dataverse-Plattform vor; die gebräuchlichsten sind:
| TypeMask | Teilnehmerrolle |
|---|---|
1 | From (Absender) |
2 | To (Empfänger) |
3 | CC |
4 | BCC |
Diese Tabelle ist eine Plattform-Referenz, keine Festlegung der DataBridge. Die
verbindliche und vollständige Liste steht in der Microsoft-Dokumentation zur Entität
activityparty.
LinkToRecord
Erzeugt eine anklickbare URL zu einem Datensatz in Dataverse.
{
"Operations": [
{
"Name": "LinkToRecord",
"Parameters": {
"BaseUrl": "https://<org>.crm4.dynamics.com/main.aspx?appid=<AppId>&pagetype=entityrecord"
}
}
]
}
TargetOperations
Lookup
Befüllt ein Lookup-Feld in Dataverse, indem der verknüpfte Datensatz über eine
Feldwert-Kombination gesucht wird. Die Operation gehört in die Spalte TargetOperation
des Mappings und benötigt zwingend den Operations-Rahmen, den Namen Lookup sowie
TargetTable.
{
"Operations": [
{
"Name": "Lookup",
"Parameters": {
"TargetTable": "wysa_countryregion",
"TargetKey": {
"KeyType": "CustomKey",
"KeyName": "wysa_code",
"KeyValues": [
{ "keyName": "wysa_code", "attributeName": "countryRegionCode", "rank": 1 }
]
}
}
}
]
}
Ohne TargetTable ist nicht bestimmt, in welcher Entität gesucht werden soll — die
Operation schlägt fehl. Fehlt der Operations-Rahmen oder der Name, wird die Operation
gar nicht erst erkannt und die Verarbeitung bricht mit Lookup Operation missing ab.
Wird kein passender Datensatz gefunden, legt die DataBridge standardmäßig einen neuen an.
Weitere Parameter der TargetOperation
| Parameter | Wirkung |
|---|---|
TargetTable | Entität, in der gesucht wird. Bei Lookup Pflicht. |
TargetKey / TargetKeys | Schlüssel bzw. Schlüsselliste zur Suche (siehe oben) |
DefaultValue | Fester Wert, der ohne Suche gesetzt wird. Bei Lookup-Feldern eine GUID; bei Options-Feldern der numerische Optionswert. |
SetNullIfEqualsValueOfField | Name des Primärschlüsselfeldes. Stimmt der aufzulösende Wert mit dem Schlüssel des Quelldatensatzes überein, wird null gesetzt statt eine Selbstreferenz zu erzeugen. |
OptionDelimiter | Trennzeichen, mit dem ein Quellwert für ein MultiSelect-Feld in Einzelwerte zerlegt wird |
DoNotCreate | true verhindert die automatische Neuanlage (siehe unten) |
DoNotCreate (ab v2.1)
Ist DoNotCreate auf true gesetzt, wird der Zieldatensatz eines Lookups nur dann
verknüpft, wenn er bereits existiert. Wird er nicht gefunden, bleibt das Feld leer —
es entsteht kein neuer Datensatz.
{
"Operations": [
{
"Name": "Lookup",
"Parameters": {
"TargetTable": "wysa_countryregion",
"DoNotCreate": true,
"TargetKey": {
"KeyType": "CustomKey",
"KeyName": "wysa_code",
"KeyValues": [
{ "keyName": "wysa_code", "attributeName": "countryRegionCode", "rank": 1 }
]
}
}
}
]
}
OptionMapping
Übersetzt Quellwerte in numerische Dataverse-Optionset-Werte.
{
"Operations": [
{
"Name": "OptionMapping",
"Parameters": {
"Mapping": [
{ "Key": "Blank", "Value": "" },
{ "Key": "Prospect", "Value": "383380000" },
{ "Key": "First_x002D_time_x0020_Donor", "Value": "383380001" },
{ "Key": "Recurring_x0020_Donor", "Value": "383380002" }
]
}
}
]
}
Ein leerer Value setzt das Zielfeld auf null. Ein Quellwert, der in der Liste nicht
vorkommt, führt zum Abbruch (Could not find TableMapping for …).
In der Praxis liefert Business Central Sonderzeichen in Optionswerten kodiert:
Leerzeichen als _x0020_, Bindestrich als _x002D_. Diese kodierten Werte sind als Key
exakt so einzutragen, wie sie von BC geliefert werden.
Es handelt sich um eine Beobachtung aus laufenden Installationen, nicht um eine
Umwandlung, die die DataBridge selbst vornimmt — der Vergleich erfolgt zeichengenau
(Groß-/Kleinschreibung wird ignoriert). Im Zweifel den tatsächlich gelieferten Wert über
logReceivedData an der Quellverbindung prüfen.
Datentypen — Zieltyp und akzeptierte Quelltypen
Beim Schreiben bestimmt der Attributtyp des Zielfeldes aus den Dataverse-Metadaten, welche Umwandlung angewendet wird.
| Zielattribut (Dataverse) | Akzeptierte Quelltypen | Verhalten und Sonderfälle |
|---|---|---|
BigIntAttributeMetadata | int64, int32 | Leerwert → null |
BooleanAttributeMetadata | boolean, string | Leerwert → null |
DateTimeAttributeMetadata | date, datetime, string | Leerwert → null; auch 0001-01-01 wird zu null |
DecimalAttributeMetadata | decimal, money | Interpretation mit der Kultur aus language |
DecimalAttributeMetadata | string (ab v2.1) | Interpretation immer als en-US, unabhängig von language |
DoubleAttributeMetadata | double, decimal | Interpretation mit der Kultur aus language. string wird nicht akzeptiert. |
EntityNameAttributeMetadata | alle Quelltypen | Wird als Text behandelt; Leerwert → null |
IntegerAttributeMetadata | int32, optionsetvalue, string | Leerwert → null |
LookupAttributeMetadata | typunabhängig | Erfordert eine Lookup- oder DefaultValue-TargetOperation, sonst Lookup Operation missing |
MemoAttributeMetadata | alle Quelltypen | Wird als Text behandelt; Leerwert → null |
MoneyAttributeMetadata | nur decimal | money, double und string führen zum Abbruch |
MultiSelectPicklistAttributeMetadata | nur string | Erfordert OptionMapping; Zerlegung über OptionDelimiter. Leerwert → null |
PicklistAttributeMetadata | string, int32 | Erfordert OptionMapping oder DefaultValue |
StateAttributeMetadata | boolean, string, int32 | Erfordert OptionMapping oder DefaultValue |
StatusAttributeMetadata | string, int32 | Erfordert OptionMapping oder DefaultValue |
StringAttributeMetadata | alle Quelltypen | Wert wird getrimmt; Leerwert → null |
Sonderfälle jenseits der Tabelle:
UniqueIdentifierAttributeMetadatasowie Primärschlüssel- und logische Attribute (z. B.statuscodename) werden beim Schreiben stillschweigend übersprungenFileAttributeMetadataundImageAttributeMetadatawerden nicht unterstützt (type not supported)- Jeder sonstige, nicht aufgeführte Attributtyp führt zum Abbruch
(
Type … not yet implemented)
Die drei numerischen Zieltypen akzeptieren nicht dieselben Quelltypen:
Decimalakzeptiert seit v2.1 auchstring— dann aber immer im Formaten-US. Ein deutsch formatierter Text wie1.234,56wird dabei falsch oder gar nicht gelesen.Moneyakzeptiert ausschließlichdecimal. Ein Quellfeld, das alsmoneyoderdoubletypisiert ankommt, führt zum Abbruch — auch wenn der Wert inhaltlich passt.Doubleakzeptiert keinenstring.
Zeigt ein Mapping Source Type not yet implemented, liegt in aller Regel eine dieser drei
Abweichungen vor.
Sonderentitäten
Einige Dataverse-Entitäten werden nicht über den generischen Weg verarbeitet.
listmember — Marketinglisten
Datensätze der Entität listmember werden nicht über den generischen Schreibpfad
angelegt oder gelöscht, sondern über die Dataverse-Nachrichten AddMemberList bzw.
RemoveMemberList. Das Mapping muss daher die Felder listid und entityid befüllen —
sie liefern die Kennungen für die beiden Nachrichten.
Entitäten ohne statuscode
Für die folgenden Entitäten wird das Attribut statuscode beim Lesen automatisch aus der
Spaltenliste entfernt, weil sie es nicht besitzen:
| Entität |
|---|
listmember |
quotedetail |
opportunityproduct |
salesorderdetail |
Ein Job-Filter mit der Operation StatusCode ist für diese Entitäten folglich nicht
verwendbar.
Job-Filter
Der CE-Konnektor wertet das Feld Filter des Jobs clientseitig aus: Die Datensätze
werden über die Change Tracking API abgerufen und anschließend geprüft; nicht passende
Datensätze werden verworfen.
Unterstützt werden die Operationen Equals, Boolean, OptionSetValue, NotNull,
IsNull und StatusCode. Ein anderer Operationsname führt zum Abbruch
(Undefined FilterOperation).
Syntax, Parameter und Beispiele sind unter Jobs → Filter-Syntax beschrieben.
Änderungserkennung (Watermark)
| Eigenschaft | Wert |
|---|---|
| Empfohlener WatermarkType | string |
| WatermarkField | beliebig (wird von der Change Tracking API intern verwaltet) |
Der CE-Konnektor nutzt die Dataverse Change Tracking API. Diese liefert bei jedem Abruf einen opaken Token, der beim nächsten Aufruf übergeben wird. So werden alle Änderungen erfasst — auch wenn der Timer genau während einer Änderung ausgeführt wird.