ASP.NET Web API ile OData v4'te Karmaşık Tür DevralmaComplex Type Inheritance in OData v4 with ASP.NET Web API

Microsoft tarafındanby Microsoft

OData v4 belirtiminegöre, karmaşık bir tür başka bir karmaşık türden devralınabilir.According to the OData v4 specification, a complex type can inherit from another complex type. (Karmaşık complex bir tür, anahtarı olmayan yapılandırılmış bir türdür.) Web API OData 5.3 karmaşık tür devralma destekler.(A complex type is a structured type without a key.) Web API OData 5.3 supports complex type inheritance.

Bu konu, karmaşık devralma türlerine sahip bir varlık veri modelinin (EDM) nasıl oluşturulabildiğini gösterir.This topic shows how to build an entity data model (EDM) with complex inheritance types. Kaynak kodun tamamı için Bkz. OData Complex Türü Devralma Örneği.For the complete source code, see OData Complex Type Inheritance Sample.

Öğreticide kullanılan yazılım sürümleriSoftware versions used in the tutorial

  • Web API OData 5.3Web API OData 5.3
  • OData v4OData v4

Model HiyerarşisiModel Hierarchy

Karmaşık tür devralmagöstermek için aşağıdaki sınıf hiyerarşisini kullanacağız.To illustrate complex type inheritance, we'll use the following class hierarchy.

Shapesoyut karmaşık bir türüdür.Shape is an abstract complex type. Rectangle, Triangle, Circle ve türetilen Shapekarmaşık RoundRectangle türleri , Rectangleve türetilmiştir .Rectangle, Triangle, and Circle are complex types derived from Shape, and RoundRectangle derives from Rectangle. Windowbir varlık türüdür ve Shape bir örnek içerir.Window is an entity type and contains a Shape instance.

Bu türleri tanımlayan CLR sınıfları aşağıda verilmiştir.Here are the CLR classes that define these 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
}

EDM Modelini OluşturunBuild the EDM Model

EDM oluşturmak için, CLR türlerinden kalıtım ilişkileri çıkarımlar ODataConventionModelBuilderkullanabilirsiniz.To create the EDM, you can use ODataConventionModelBuilder, which infers the inheritance relationships from the CLR types.

private IEdmModel GetEdmModel()
{
    ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<Window>("Windows");
    return builder.GetEdmModel();
}

Ayrıca açıkça EDM oluşturabilirsiniz, ODataModelBuilderkullanarak.You can also build the EDM explicitly, using ODataModelBuilder. Bu daha fazla kod alır, ancak EDM üzerinde daha fazla kontrol sağlar.This takes more code, but gives you more control over the 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();
}

Bu iki örnek aynı EDM şema oluşturmak.These two examples create the same EDM schema.

Meta veri belgesiMetadata Document

Burada karmaşık tür devralma gösteren OData meta veri belgesi.Here is the OData metadata document, showing complex type inheritance.

<?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>

Meta veri belgesinden şunları görebilirsiniz:From the metadata document, you can see that:

  • Karmaşık Shape türü soyuttur.The Shape complex type is abstract.
  • , Rectangle Triangleve Circle karmaşık türü taban Shapetürüne sahiptir.The Rectangle, Triangle, and Circle complex type have the base type Shape.
  • Türü RoundRectangle taban türü Rectanglevardır.The RoundRectangle type has the base type Rectangle.

Döküm Karmaşık TürleriCasting Complex Types

Karmaşık türleri döküm şimdi desteklenir.Casting on complex types is now supported. Örneğin, aşağıdaki sorgu a'dan Shape Rectanglebir'eFor example, the following query casts a Shape to a Rectangle.

GET ~/odata/Windows(1)/Shape/NS.Rectangle/LeftTop

Yanıt yükü aşağıda veda eder:Here's the response payload:

{ 
   "@odata.context":"http://localhost/odata/$metadata#Windows(1)/Shape/NS.Rectangle/LeftTop",
    "X":100,"Y":100
}