Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Applies To: # OData Core lib v6 supported OData Core Lib V6
Referential constraints ensure that entities being referenced (principal entities) always exist. In OData, having one or more referential constraints defined for a partner navigation property on a dependent entity type also enables users to address the related dependent entities from principal entities using shortened key predicates (see [OData-URL]). A referential constraint in OData consists of one principal property (the ID property of the entity being referenced) and one dependent property (the ID property to reference another entity). This section shows how to define referential constraints on a partner navigation property.
Sample
Create an entity type Test.Customer
with a key property id
of Edm.String
.
var model = new EdmModel();
var customer = new EdmEntityType("Test", "Customer", null, false, true);
var customerId = customer.AddStructuralProperty("id", EdmPrimitiveTypeKind.String, false);
customer.AddKeys(customerId);
model.AddElement(customer);
Create an entity type Test.Order
with a composite key consisting of two key properties customerId
and orderId
both of Edm.String
.
var order = new EdmEntityType("Test", "Order", null, false, true);
var orderCustomerId = order.AddStructuralProperty("customerId", EdmPrimitiveTypeKind.String, true);
var orderOrderId = order.AddStructuralProperty("orderId", EdmPrimitiveTypeKind.String, true);
order.AddKeys(orderCustomerId, orderOrderId);
model.AddElement(order);
Customer.id
is the principal property while Order.customerId
is the dependent property. Create a navigation property orders
on the principal entity type customer
.
var customerOrders = customer.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
{
ContainsTarget = true,
Name = "orders",
Target = order,
TargetMultiplicity = EdmMultiplicity.Many
});
Then, create its corresponding partner navigation property on the dependent entity type order
with referential constraint.
var orderCustomer = order.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
{
ContainsTarget = false,
Name = "customer",
Target = customer,
TargetMultiplicity = EdmMultiplicity.One,
DependentProperties = new[] { orderCustomerId },
PrincipalProperties = new[] { customerId }
});
Create an entity type Test.Detail
with a composite key consisting of three key properties customerId
of Edm.String
, orderId
of Edm.String
and id
of Edm.Int32
.
var detail = new EdmEntityType("Test", "Detail");
var detailCustomerId = detail.AddStructuralProperty("customerId", EdmPrimitiveTypeKind.String);
var detailOrderId = detail.AddStructuralProperty("orderId", EdmPrimitiveTypeKind.String);
detail.AddKeys(detailCustomerId, detailOrderId, detail.AddStructuralProperty("id", EdmPrimitiveTypeKind.Int32, false));
model.AddElement(detail);
Create an entity type Test.DetailedOrder
which is a derived type of Test.Order
. We will use this type to illustrate type casting in between multiple navigation properties.
var detailedOrder = new EdmEntityType("Test", "DetailedOrder", order);
Come back to the type Test.Detail
. There are two referential constraints here:
DetailedOrder.orderId
is the principal property whileDetail.orderId
is the dependent property.DetailedOrder.customerId
is the principal property whileDetail.customerId
is the dependent property.
Create a navigation property details
.
var detailedOrderDetails = detailedOrder.AddUnidirectionalNavigation(
new EdmNavigationPropertyInfo
{
ContainsTarget = true,
Name = "details"
Target = detail,
TargetMultiplicity = EdmMultiplicity.Many
});
model.AddElement(detailedOrder);
Then, create its corresponding partner navigation property on the dependent entity type detail
with referential constraint.
var detailDetailedOrder = detail.AddUnidirectionalNavigation(
new EdmNavigationPropertyInfo
{
ContainsTarget = false,
Name = "detailedOrder"
Target = detailedOrder,
TargetMultiplicity = EdmMultiplicity.One,
DependentProperties = new[] { detailOrderId, detailCustomerId },
PrincipalProperties = new[] { orderOrderId, orderCustomerId }
});
Please note that you should NOT specify Customer.id
as the principal property because the association (represented by the navigation property details
) is from DetailedOrder
to Detail
rather than from Customer
to Detail
. And those properties must be specified in the same order.
Then you can query the details
either by a full key predicate
https://host/customers('customerId')/orders(customerId='customerId',orderId='orderId')/Test.DetailedOrder/details(customerId='customerId',orderId='orderId',id=1)
or a shortened key predicate.
https://host/customers('customerId')/orders('orderId')/Test.DetailedOrder/details(1)
Key-as-segment convention is also supported.
https://host/customers/customerId/orders/orderId/Test.DetailedOrder/details/1