Skip to content

Commit

Permalink
Set schema for out-of-line annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
gathogojr committed Oct 13, 2023
1 parent 9c6f147 commit 308e063
Show file tree
Hide file tree
Showing 2 changed files with 196 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Odata-docs/TOC.yml
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@
href: /odata/odatalib/navigation-partner
- name: Optional parameters
href: /odata/odatalib/optional-parameters
- name: Set schema for out-of-line annotations
href: /odata/odatalib/edm/set-annotations-schema
- name: Batching
items:
- name: Batching requests
Expand Down
194 changes: 194 additions & 0 deletions Odata-docs/odatalib/v7/edm/set-annotations-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
---
title: "Set schema for out-of-line annotations"
description: "Set schema for out-of-line annotations"
author: gathogojr
ms.author: jogathog
ms.date: 10/9/2023
ms.topic: article

---
# Set schema for out-of-line annotations
**Applies To**: [!INCLUDE[appliesto-odataclient](../../../includes/appliesto-odatalib-v7.md)]

Edm library supports adding annotations on various schema elements, including entity sets, entity types, properties, and so on. Annotations can be put under the `Annotations` element (**out-of-line** annotations), or under the annotated target schema element** (**inline** annotations).

You may want to go through the [define annotations](/odata/odatalib/edm/define-annotations) tutorial to understand how to specify the serialization location for an annotation.

This page shows how to specify the schema that the out-of-line annotations should appear in.

In the section, we define a simple Edm model in an ASP.NET Core project to demonstrate how out-of-line annotations are represented in the service document:

## Create an ASP.NET Core application
Create an ASP.NET Core application based on the ASP.NET Core Empty template and import the `Microsoft.AspNetCore.OData` nuget package:

---

# [Visual Studio](#tab/visual-studio)

In the Visual Studio **Package Manager Console**:
```powershell
Install-Package Microsoft.AspNetCore.OData
```

# [.NET Core CLI](#tab/netcore-cli)

```dotnetcli
dotnet add package Microsoft.AspNetCore.OData
```

---

## Configure the OData service and build the Edm model
Replace the contents of _Program.cs_ file with the following code:

```csharp
using Microsoft.AspNetCore.OData;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;

var builder = WebApplication.CreateBuilder(args);

var model = new EdmModel();

// Add Employee entity to Ns namespace
var employeeEntityType = new EdmEntityType("Ns", "Employee");
employeeEntityType.AddKeys(
employeeEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false));
employeeEntityType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, isNullable: true);
employeeEntityType.AddStructuralProperty("Salary", EdmPrimitiveTypeKind.Decimal, isNullable: false);
model.AddElement(employeeEntityType);

// Add Entity Container to Default namespace
var defaultEntityContainer = new EdmEntityContainer("Default", "Container");
model.AddElement(defaultEntityContainer);

// Add Employee entity set to the entity container
var employeesEntitySet = defaultEntityContainer.AddEntitySet("Employees", employeeEntityType);

// Add out-of-line vocabulary annotation
var notSortableVocabularyAnnotation = new EdmVocabularyAnnotation(
employeesEntitySet,
new EdmTerm("Org.OData.Capabilities.V1", "SortRestrictions", new EdmEntityTypeReference(employeeEntityType, isNullable: false)),
new EdmRecordExpression(
new EdmPropertyConstructor("Sortable", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("AscendingOnlyProperties", new EdmCollectionExpression()),
new EdmPropertyConstructor("DescendingOnlyProperties", new EdmCollectionExpression()),
new EdmPropertyConstructor("NonSortableProperties", new EdmCollectionExpression(
new EdmPropertyPathExpression("Salary")))));
model.AddVocabularyAnnotation(notSortableVocabularyAnnotation);

// Configure OData service
builder.Services.AddControllers().AddOData(
options => options.AddRouteComponents(
model));

var app = builder.Build();

app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());

app.Run();
```

## Run the service
Run the application and query the service metadata:
```http
GET http://localhost:5000/$metadata
```

Response:
```xml
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="Ns" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Employee">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<Property Name="Salary" Type="Edm.Decimal" Nullable="false" Scale="Variable" />
</EntityType>
<Annotations Target="Default.Container/Employees">
<Annotation Term="Org.OData.Capabilities.V1.SortRestrictions">
<Record>
<PropertyValue Property="Sortable" Bool="true" />
<PropertyValue Property="AscendingOnlyProperties">
<Collection />
</PropertyValue>
<PropertyValue Property="DescendingOnlyProperties">
<Collection />
</PropertyValue>
<PropertyValue Property="NonSortableProperties">
<Collection>
<PropertyPath>Salary</PropertyPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
</Schema>
<Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="Container">
<EntitySet Name="Employees" EntityType="Ns.Employee" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
```

The `Org.OData.Capabilities.V1.SortRestrictions` annotation appears under an `Annotations` element in the `Ns` namespace.

## Set the schema the annotation should appear in
The following two steps show how to specify the schema the annotation should appear in:
1. Import `Microsoft.OData.Edm.Csdl` namespace.
2. Use the `SetSchemaNamespace` to set the schema namespace:
```csharp
// ... rest of the Edm model definition code
model.AddVocabularyAnnotation(notSortableVocabularyAnnotation);
notSortableVocabularyAnnotation.SetSchemaNamespace(model, "Default");
```

## Rerun the service
Rerun the application and query the service metadata. This time round the `Annotations` element is in the `Default` namespace:
```xml
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="Ns" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Employee">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<Property Name="Salary" Type="Edm.Decimal" Nullable="false" Scale="Variable" />
</EntityType>
</Schema>
<Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="Container">
<EntitySet Name="Employees" EntityType="Ns.Employee" />
</EntityContainer>
<Annotations Target="Default.Container/Employees">
<Annotation Term="Org.OData.Capabilities.V1.SortRestrictions">
<Record>
<PropertyValue Property="Sortable" Bool="true" />
<PropertyValue Property="AscendingOnlyProperties">
<Collection />
</PropertyValue>
<PropertyValue Property="DescendingOnlyProperties">
<Collection />
</PropertyValue>
<PropertyValue Property="NonSortableProperties">
<Collection>
<PropertyPath>Salary</PropertyPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
```

0 comments on commit 308e063

Please sign in to comment.