ASP.NET Web API を使用した OData v4 での複合型の継承
提供元: Microsoft
OData v4 仕様によると、複合型は別の複合型から継承できます。 ("複合" 型は、キーのない構造化型です)。Web API OData 5.3 では、複合型の継承がサポートされています。
このトピックでは、複雑な継承型を使用してエンティティ データ モデル (EDM) を構築する方法について説明します。
チュートリアルで使用するソフトウェアのバージョン
- Web API OData 5.3
- OData v4
モデル階層
複合型の継承を示すために、次のクラス階層を使用します。
Shape
は抽象複合型です。 Rectangle
、Triangle
、および Circle
は、Shape
から派生した複合型であり、RoundRectangle
は Rectangle
から派生します。 Window
はエンティティ型であり、Shape
インスタンスを含みます。
これらの型を定義する CLR クラスを次に示します。
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
}
EDM モデルをビルドする
EDM を作成するには、CLR 型からの継承リレーションシップを推論する ODataConventionModelBuilder を使用できます。
private IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Window>("Windows");
return builder.GetEdmModel();
}
ODataModelBuilder を使用して、EDM を明示的にビルドすることもできます。 これにはより多くのコードが必要ですが、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();
}
これら 2 つの例では、同じ EDM スキーマを作成します。
メタデータ ドキュメント
複合型の継承を示す OData メタデータ ドキュメントを次に示します。
<?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>
メタデータ ドキュメントから、次のことがわかります。
Shape
複合型は抽象型です。Rectangle
、Triangle
、およびCircle
複合型には、基本型Shape
があります。RoundRectangle
型には基本型Rectangle
があります。
複合型のキャスト
複合型でのキャストがサポートされるようになりました。 たとえば、次のクエリは Shape
を Rectangle
にキャストします。.
GET ~/odata/Windows(1)/Shape/NS.Rectangle/LeftTop
応答ペイロードを次に示します。
{
"@odata.context":"http://localhost/odata/$metadata#Windows(1)/Shape/NS.Rectangle/LeftTop",
"X":100,"Y":100
}