O protocolo OData requer que todas as entidades possam ser endereçadas por sua forma canônica. Isso significa que cada entidade deve incluir a chave da entidade raiz particionada, a raiz do esquema.
/Customer('ACME')/order(100)
No WCF Data Services, a entidade-filha deve ser diretamente endereçável, o que significa que a chave na raiz do esquema deve fazer parte da chave da filha: /Order(customer_customerId='ACME', orderId=100). Isso é conseguido por meio da criação de uma associação com a entidade raiz, em que a associação um-para-um ou muitos-para-um com a entidade raiz também é identificada como uma chave. Quando entidades são incluídas como parte da chave, os atributos da entidade pai são expostos como propriedades-chave.
O diagrama do esquema de entidade Cliente/Ordem ilustra como cada entidade é particionada usando o Cliente. A entidade Order inclui Customer como parte de sua chave e é, portanto, diretamente acessível. O serviço de dados REST expõe todas as associações chave como propriedades individuais: Order tem customer_customerId e OrderDetail tem order_customer_customerId e order_orderId.
Utilizando a API EntityManager, é possível localizar Order utilizando o id de Customer e Order:
transaction.begin();
// Look-up the Order using the Customer. We only include the Id
// in the Customer class when building the OrderId key instance.
Order order = (Order) em.find(Order.class,
new OrderId(100, new Customer('ACME')));
...
transaction.commit();
/Order(orderId=100, customer_customerId='ACME')
/Customer('ACME')/orders?$filter=orderId eq 100
A chave do cliente é endereçada utilizando o nome do atributo da entidade Customer, um caractere sublinhado e o nome do atributo do id de Customer: customer_customerId.
Uma entidade também pode incluir uma entidade não raiz como parte de sua chave se todos os ancestrais para a entidade não raiz tiverem associações de chave com a raiz. Neste exemplo, OrderDetail tem uma associação de chave com Order, e Order tem uma associação de chave com a entidade Customer raiz. Utilizando a API EntityManager:
transaction.begin();
// Construct an OrderDetailId key instance. It includes
// The Order and Customer with only the keys set.
Customer customerACME = new Customer("ACME");
Order order100 = new Order(100, customerACME);
OrderDetailId orderDetailKey =
new OrderDetailId(order100, "COMP");
OrderDetail orderDetail = (OrderDetail)
em.find(OrderDetail.class, orderDetailKey);
...
O serviço de dados REST permite endereçar OrderDetail diretamente:
/OrderDetail(productId=500,
order_customer_customerId='ACME', order_orderId =100)
A associação da entidade OrderDetail com a entidade Product foi quebrada para permitir o particionamento de Orders e Product Inventory independentemente. A entidade OrderDetail armazena o ID do produto e categoria de um relacionamento sólido. Ao desacoplar os dois esquemas de entidade, apenas uma partição é acessada por vez.
O esquema Categoria e Produto ilustrado no diagrama mostra que a entidade-raiz é Categoria e cada Produto tem uma associação com uma entidade Categoria. A entidade Category está incluída na identidade de Product. O serviço de dados REST expõe uma propriedade-chave: category_categoryId, que permite o endereçamento direto de Product.
Como Categoria é a entidade-raiz, em um ambiente particionado, a Categoria deve ser conhecida para localizar o Produto. Utilizando a API EntityManager, a transação deve ser retida na entidade Category antes de localizar Product.
Utilizando a API EntityManager:
transaction.begin();
// Create the Category root entity with only the key. This
// allows us to construct a ProductId without needing to find
// The Category first. The transaction is now pinned to the
// partition where Category "COMP" is stored.
Category cat = new Category("COMP");
Product product = (Product) em.find(Product.class,
new ProductId(500, cat));
...
O serviço de dados REST permite endereçar Product diretamente:
/Product(productId=500,
category_categoryId='COMP')