Skip to main content

CDC Sink: Linked Tables

  • A linked table writes a RavenDB document ID reference instead of embedding related data.
    CDC Sink builds the ID from LinkedCollectionName and the configured JoinColumns.

  • CdcSinkLinkedTableConfig does not create, load, or maintain the referenced document. The referenced document is maintained by CDC Sink only when that source table is also configured as a root table in the task.

  • In this article:

Basic configuration

CdcSinkLinkedTableConfig is added to the LinkedTables list of a root or embedded table configuration:

new CdcSinkTableConfig
{
CollectionName = "Orders",
SourceTableName = "orders",
PrimaryKeyColumns = ["id"],
Columns =
[
new CdcColumnMapping() { Column = "id", Name = "Id" },
],
LinkedTables =
[
new CdcSinkLinkedTableConfig
{
SourceTableName = "customers",
PropertyName = "Customer", // Property name in document
LinkedCollectionName = "Customers", // Target collection for ID
JoinColumns = ["customer_id"] // FK used to build the document ID
}
]
}

With customer_id = 42, the Orders document gets:

{
"Id": 1,
"Customer": "Customers/42"
}

If all join column values are null, CDC Sink sets the link property to null.

The Customer property is a RavenDB document ID built from LinkedCollectionName and the source-row values in JoinColumns. The join column values are appended to LinkedCollectionName in the order listed. Use the same order as the referenced table's PrimaryKeyColumns, so the generated ID matches the referenced document ID.

This configuration only writes the "Customers/42" reference into the Orders document.
The Customers/42 document itself exists only if the customers table is also configured as a root table.

When loading the parent document, use includes to fetch the referenced document without a second network call.

Composite foreign keys

For a reference to a table with a composite primary key,
list the matching foreign-key columns in JoinColumns in the same order:

new CdcSinkLinkedTableConfig
{
SourceTableName = "customers",
PropertyName = "Customer",
LinkedCollectionName = "Customers",

// Must match the referenced table's PK order
JoinColumns = ["customer_region", "customer_id"]
}

With customer_region = 'US' and customer_id = 42, the document gets:

"Customer": "Customers/US/42"

Linked vs embedded

ConsiderationEmbeddedLinked
Data storedFull nested object/array inside documentDocument ID reference only
Load patternSingle document loadLoad parent, then include/load referenced documents
Document sizeGrows with embedded itemsParent document stays small
Related-row updatesUpdate the embedded data in the parent documentUpdate the referenced document only when that table is also configured as a root table
Relationship modelRelated data is owned by the parentReferenced entity exists independently
Typical useOrders own LineItemsOrders reference Customers

  • Choose embedded when the child data belongs to the parent and is always read together with it.

  • Choose linked when the referenced entity is independently meaningful and shared across many parents,
    and you want to avoid duplicating data.