Héritage de type complexe dans OData v4 avec API Web ASP.NET
par Microsoft
Selon la spécification OData v4, un type complexe peut hériter d’un autre type complexe. (Un type complexe est un type structuré sans clé.) L’API web OData 5.3 prend en charge l’héritage de type complexe.
Cette rubrique montre comment créer un modèle de données d’entité (EDM) avec des types d’héritage complexes.
Versions logicielles utilisées dans le tutoriel
- API web OData 5.3
- OData v4
Hiérarchie de modèle
Pour illustrer l’héritage de type complexe, nous allons utiliser la hiérarchie de classes suivante.
Shape
est un type complexe abstrait. Rectangle
, Triangle
et Circle
sont des types complexes dérivés de Shape
et RoundRectangle
dérivent de Rectangle
. Window
est un type d’entité et contient un Shape
instance.
Voici les classes CLR qui définissent ces types.
public class Window
{
public int Id { get; set; }
public string Title { get; set; }
public Shape Shape { get; set; }
}
public abstract class Shape
{
public bool HasBorder { get; set; }
public Color Color { get; set; }
}
public class Rectangle : Shape
{
public Point LeftTop { get; set; }
public int Height { get; set; }
public int Weight { get; set; }
}
public class RoundRectangle : Rectangle
{
public double Round { get; set; }
}
public class Triangle : Shape
{
public Point P1 { get; set; }
public Point P2 { get; set; }
public Point P3 { get; set; }
}
public class Circle : Shape
{
public Point Center { get; set; }
public int Radius { get; set; }
}
public class Point
{
public int X { get; set; }
public int Y { get; set; }
}
public enum Color
{
Red,
Blue,
Green,
Yellow
}
Générer le modèle EDM
Pour créer l’EDM, vous pouvez utiliser ODataConventionModelBuilder, qui déduit les relations d’héritage des types CLR.
private IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Window>("Windows");
return builder.GetEdmModel();
}
Vous pouvez également générer explicitement l’EDM à l’aide d’ODataModelBuilder. Cela nécessite plus de code, mais vous donne plus de contrôle sur l’EDM.
private IEdmModel GetExplicitEdmModel()
{
ODataModelBuilder builder = new ODataModelBuilder();
EnumTypeConfiguration<Color> color = builder.EnumType<Color>();
color.Member(Color.Red);
color.Member(Color.Blue);
color.Member(Color.Green);
color.Member(Color.Yellow);
ComplexTypeConfiguration<Point> point = builder.ComplexType<Point>();
point.Property(c => c.X);
point.Property(c => c.Y);
ComplexTypeConfiguration<Shape> shape = builder.ComplexType<Shape>();
shape.EnumProperty(c => c.Color);
shape.Property(c => c.HasBorder);
shape.Abstract();
ComplexTypeConfiguration<Triangle> triangle = builder.ComplexType<Triangle>();
triangle.ComplexProperty(c => c.P1);
triangle.ComplexProperty(c => c.P2);
triangle.ComplexProperty(c => c.P2);
triangle.DerivesFrom<Shape>();
ComplexTypeConfiguration<Rectangle> rectangle = builder.ComplexType<Rectangle>();
rectangle.ComplexProperty(c => c.LeftTop);
rectangle.Property(c => c.Height);
rectangle.Property(c => c.Weight);
rectangle.DerivesFrom<Shape>();
ComplexTypeConfiguration<RoundRectangle> roundRectangle = builder.ComplexType<RoundRectangle>();
roundRectangle.Property(c => c.Round);
roundRectangle.DerivesFrom<Rectangle>();
ComplexTypeConfiguration<Circle> circle = builder.ComplexType<Circle>();
circle.ComplexProperty(c => c.Center);
circle.Property(c => c.Radius);
circle.DerivesFrom<Shape>();
EntityTypeConfiguration<Window> window = builder.EntityType<Window>();
window.HasKey(c => c.Id);
window.Property(c => c.Title);
window.ComplexProperty(c => c.Shape);
builder.EntitySet<Window>("Windows");
return builder.GetEdmModel();
}
Ces deux exemples créent le même schéma EDM.
Document de métadonnées
Voici le document de métadonnées OData, montrant l’héritage de type complexe.
<?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="Window">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false" />
<Property Name="Title" Type="Edm.String" />
<Property Name="Shape" Type="BookStore.Shape" />
</EntityType>
<ComplexType Name="Shape" Abstract="true">
<Property Name="HasBorder" Type="Edm.Boolean" Nullable="false" />
<Property Name="Color" Type="BookStore.Color" Nullable="false" />
</ComplexType>
<ComplexType Name="Circle" BaseType="BookStore.Shape">
<Property Name="Center" Type="BookStore.Point" />
<Property Name="Radius" Type="Edm.Int32" Nullable="false" />
</ComplexType>
<ComplexType Name="Point">
<Property Name="X" Type="Edm.Int32" Nullable="false" />
<Property Name="Y" Type="Edm.Int32" Nullable="false" />
</ComplexType>
<ComplexType Name="Rectangle" BaseType="BookStore.Shape">
<Property Name="LeftTop" Type="BookStore.Point" />
<Property Name="Height" Type="Edm.Int32" Nullable="false" />
<Property Name="Weight" Type="Edm.Int32" Nullable="false" />
</ComplexType>
<ComplexType Name="RoundRectangle" BaseType="BookStore.Rectangle">
<Property Name="Round" Type="Edm.Double" Nullable="false" />
</ComplexType>
<ComplexType Name="Triangle" BaseType="BookStore.Shape">
<Property Name="P1" Type="BookStore.Point" />
<Property Name="P2" Type="BookStore.Point" />
<Property Name="P3" Type="BookStore.Point" />
</ComplexType>
<EnumType Name="Color">
<Member Name="Red" Value="0" />
<Member Name="Blue" Value="1" />
<Member Name="Green" Value="2" />
<Member Name="Yellow" Value="3" />
</EnumType>
</Schema>
<Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="Container">
<EntitySet Name="Windows" EntityType="BookStore.Window" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Dans le document de métadonnées, vous pouvez voir ce qui suit :
- Le
Shape
type complexe est abstrait. - Le
Rectangle
type complexe ,Triangle
etCircle
ont le typeShape
de base . - Le
RoundRectangle
type a le typeRectangle
de base .
Cast de types complexes
Le cast sur des types complexes est désormais pris en charge. Par exemple, la requête suivante caste un Shape
en .Rectangle
GET ~/odata/Windows(1)/Shape/NS.Rectangle/LeftTop
Voici la charge utile de réponse :
{
"@odata.context":"http://localhost/odata/$metadata#Windows(1)/Shape/NS.Rectangle/LeftTop",
"X":100,"Y":100
}