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 v7 supported OData Core Lib V7
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 type 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 type Edm.String
.
var order = new EdmEntityType("Test", "Order", null, false, true);
var orderCustomerId = order.AddStructuralProperty("customerId", EdmPrimitiveTypeKind.String, false);
var orderOrderId = order.AddStructuralProperty("orderId", EdmPrimitiveTypeKind.String, false);
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 type Edm.String
, orderId
of type Edm.String
, and id
of type Edm.Int32
.
var detail = new EdmEntityType("Test", "Detail");
var detailCustomerId = detail.AddStructuralProperty("customerId", EdmPrimitiveTypeKind.String, false);
var detailOrderId = detail.AddStructuralProperty("orderId", EdmPrimitiveTypeKind.String, false);
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 order shown.
Then you can query the details
using either full key predicate
https://host/customers('customerId')/orders(customerId='customerId',orderId='orderId')/Test.DetailedOrder/details(customerId='customerId',orderId='orderId',id=1)
or 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