CDC Sink: Linked Tables
-
A linked table writes a RavenDB document ID reference instead of embedding related data.
CDC Sink builds the ID fromLinkedCollectionNameand the configuredJoinColumns. -
CdcSinkLinkedTableConfigdoes 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:
- csharp
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:
- json
{
"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:
- csharp
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
| Consideration | Embedded | Linked |
|---|---|---|
| Data stored | Full nested object/array inside document | Document ID reference only |
| Load pattern | Single document load | Load parent, then include/load referenced documents |
| Document size | Grows with embedded items | Parent document stays small |
| Related-row updates | Update the embedded data in the parent document | Update the referenced document only when that table is also configured as a root table |
| Relationship model | Related data is owned by the parent | Referenced entity exists independently |
| Typical use | Orders own LineItems | Orders 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.