Gewusst wie: Definieren eines Modells mit 'Tabelle pro Hierarchie'-Vererbung (Entity Framework)

In diesem Thema wird beschrieben, wie manuell ein konzeptionelles Modell erstellt wird, das über eine "Tabelle pro Hierarchie"-Vererbung verfügt. Die "Tabelle pro Hierarchie"-Vererbung verwaltet mithilfe einer Datenbanktabelle die Daten aller Entitätstypen in einer Vererbungshierarchie.

Bb738443.note(de-de,VS.100).gifHinweis:
Es wird empfohlen, zum Definieren eines Modells mit "Tabelle pro Typ"-Vererbung die ADO.NET Entity Data Model Tools zu verwenden.Weitere Informationen finden Sie unter Walkthrough: Mapping Inheritance - Table-per-Hierarchy.

Die grundlegenden Schritte zum manuellen Definieren eines Modells mit "Tabelle pro Hierarchie"-Vererbung sind die folgenden:

  1. Definieren Sie eine Entitätenmenge im konzeptionellen Modell, die den Basisentitätstyp und die abgeleiteten Typen enthält. Weitere Informationen finden Sie unter EntitySet-Element (CSDL).

  2. Definieren Sie mithilfe des BaseType-Attributs abgeleitete Entitätstypen im konzeptionellen Modell, und definieren Sie nur nicht geerbte Eigenschaften für die abgeleiteten Typen. Weitere Informationen finden Sie unter EntityType-Element (CSDL).

  3. Wählen Sie eine Spalte der zugrunde liegenden Datenbanktabelle aus, mit deren Wert zwischen dem Basistyp und den abgeleiteten Typen unterschieden wird. Wenn eine Employee-Tabelle beispielsweise über die EmployeeType-Spalte mit einem ganzzahligen Wert verfügt, kann mithilfe des Werts dieser Spalte unterschieden werden, ob es sich bei einem Employee-Basisentitätstyp um einen der folgenden abgeleiteten Entitätstypen handelt: HourlyEmployee oder SalariedEmployee. Weitere Informationen finden Sie im folgenden Beispiel.

    Die Diskriminatorspalte wird als Teil einer Bedingung zugeordnet, sodass für keinen Entitätstypen in der Hierarchie eine entsprechende Eigenschaft vorhanden sein kann. Eine Ausnahme von dieser Regel tritt ein, wenn die Bedingung einen Is Null- oder Is Not Null-Vergleich verwendet. In diesem Fall kann die Diskriminatorspalte über eine entsprechende Eigenschaft für einen Entitätstyp verfügen.

    Wenn die Diskriminatorspalte über mehr als zwei Werte (z. B. einen ganzzahligen Typ) verfügen kann, muss die Spalte NULL zulassen oder über einen Standardwert verfügen. Dadurch wird sichergestellt, dass die Spalte beim Erstellen und Speichern eines neuen Typs in der Datenbank NULL sein kann oder über einen Wert verfügt.

    Zum Zuordnen der einzelnen abgeleiteten Typen in der Hierarchie müssen Bedingungen verwendet werden. Bei der Zuordnung des Basistyps können Bedingungen verwendet werden. Wenn der Basistyp abstrakt ist, sind weder Zuordnungen noch Bedingungen zulässig.

  4. Ordnen Sie den Basisentitätstyp und die abgeleitete Typen im gleichen EntitySetMapping-Element in der Mapping Specification Language (MSL) zu. Ordnen Sie ggf. geerbte Eigenschaften Tabellenspalten zu. Verwenden Sie die IsTypeOf-Syntax, wenn Sie den Wert des TypeName-Attributs für abgeleitete Typen festlegen. Unterscheiden Sie die Typen in der Hierarchie mithilfe einer Zuordnungsbedingung. Weitere Informationen finden Sie unter EntitySetMapping-Element (MSL) und Condition-Element (MSL).

Im folgenden Beispiel wird davon ausgegangen, dass Sie die Beispieldatenbank "School" installiert und das Projekt manuell zur Verwendung von Entity Framework konfiguriert haben. Weitere Informationen finden Sie unter Erstellen der Beispieldatenbank "School" (Entity Framework-Schnellstart) und Konfigurieren des Entity Framework (Entity Framework-Aufgaben).

So erstellen Sie das Speichermodell

  1. Fügen Sie dem Projekt die folgende XML-Datei hinzu, und geben Sie ihr den Namen AdventureWorks.ssdl.

    <?xml version="1.0" encoding="utf-8" ?>
    <Schema Namespace="AdventureWorksModel.Store" Alias="Self" Provider="System.Data.SqlClient"
                ProviderManifestToken="2008"
                xmlns:store="https://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
                xmlns="https://schemas.microsoft.com/ado/2009/02/edm/ssdl">
      <EntityContainer Name="AdventureWorksModelStoreContainer">
        <EntitySet Name="Product" EntityType="AdventureWorksModel.Store.Product"
                   store:Type="Tables" Schema="Production" />
      </EntityContainer>
      <EntityType Name="Product">
        <Key>
          <PropertyRef Name="ProductID" />
        </Key>
        <Property Name="ProductID" Type="int" Nullable="false"
                  StoreGeneratedPattern="Identity" />
        <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="50" />
        <Property Name="ProductNumber" Type="nvarchar" Nullable="false" MaxLength="25" />
        <Property Name="MakeFlag" Type="bit" Nullable="false" />
        <Property Name="FinishedGoodsFlag" Type="bit" Nullable="false" />
        <Property Name="Color" Type="nvarchar" MaxLength="15" />
        <Property Name="SafetyStockLevel" Type="smallint" Nullable="false" />
        <Property Name="ReorderPoint" Type="smallint" Nullable="false" />
        <Property Name="StandardCost" Type="money" Nullable="false" />
        <Property Name="ListPrice" Type="money" Nullable="false" />
        <Property Name="Size" Type="nvarchar" MaxLength="5" />
        <Property Name="SizeUnitMeasureCode" Type="nchar" MaxLength="3" />
        <Property Name="WeightUnitMeasureCode" Type="nchar" MaxLength="3" />
        <Property Name="Weight" Type="decimal" Precision="8" Scale="2" />
        <Property Name="DaysToManufacture" Type="int" Nullable="false" />
        <Property Name="ProductLine" Type="nchar" MaxLength="2" />
        <Property Name="Class" Type="nchar" MaxLength="2" />
        <Property Name="Style" Type="nchar" MaxLength="2" />
        <Property Name="ProductSubcategoryID" Type="int" />
        <Property Name="ProductModelID" Type="int" />
        <Property Name="SellStartDate" Type="datetime" Nullable="false" />
        <Property Name="SellEndDate" Type="datetime" />
        <Property Name="DiscontinuedDate" Type="datetime" />
        <Property Name="rowguid" Type="uniqueidentifier" Nullable="false" />
        <Property Name="ModifiedDate" Type="datetime" Nullable="false" />
      </EntityType>
    </Schema>
    

So erstellen Sie das konzeptionelle Modell

  1. Fügen Sie dem Projekt die folgende XML-Datei hinzu, und geben Sie ihr den Namen AdventureWorks.csdl. Beachten Sie Folgendes:

    • Für die beiden Entitätstypen Product und DiscontinuedProduct wird nur eine Entitätenmenge (Products) definiert.

    • Beim Entitätstyp DiscontinuedProduct handelt es sich um einen abgeleiteten Typ. Dies ist im BaseType-Attribut seiner Definition angegeben.

    • Die für den Entitätstyp DiscontinuedProduct definierten Eigenschaften sind lediglich nicht geerbte Eigenschaften.

    • Die MakeFlag-Spalte des Speichermodells (siehe oben in der Datei AdventureWorks.ssdl) wird für den Basistyp oder den abgeleiteten Typ nicht als Eigenschaft angezeigt. Mit dem Wert dieser Spalte wird zwischen den Typen in der Hierarchie unterschieden, die als Teil einer Bedingung zugeordnet sind (siehe unten in der Datei AdventureWorks.msl).

    Bb738443.note(de-de,VS.100).gifHinweis:
    Wenn die Spalte in einer Is Null- oder Is Not Null-Bedingung verwendet wird, kann die entsprechende Eigenschaft für einen Entitätstyp angezeigt werden.

<?xml version="1.0" encoding="utf-8" ?>
<Schema Namespace="AdventureWorksModel" Alias="Self"
              xmlns:annotation="https://schemas.microsoft.com/ado/2009/02/edm/annotation"
              xmlns="https://schemas.microsoft.com/ado/2008/09/edm">
  <EntityContainer Name="AdventureWorksEntities" annotation:LazyLoadingEnabled="true">
    <EntitySet Name="Products" EntityType="AdventureWorksModel.Product" />
  </EntityContainer>
  <EntityType Name="Product">
    <Key>
      <PropertyRef Name="ProductID" />
    </Key>
    <Property Type="Int32" Name="ProductID" Nullable="false" />
    <Property Type="String" Name="Name" Nullable="false" MaxLength="50"
              FixedLength="false" Unicode="true" />
    <Property Type="String" Name="ProductNumber" Nullable="false" MaxLength="25"
              FixedLength="false" Unicode="true" />
    <Property Type="Boolean" Name="FinishedGoodsFlag" Nullable="false" />
    <Property Type="String" Name="Color" MaxLength="15" FixedLength="false"
              Unicode="true" />
    <Property Type="Int16" Name="SafetyStockLevel" Nullable="false" />
    <Property Type="Int16" Name="ReorderPoint" Nullable="false" />
    <Property Type="Decimal" Name="StandardCost" Nullable="false"
              Precision="19" Scale="4" />
    <Property Type="Decimal" Name="ListPrice" Nullable="false"
              Precision="19" Scale="4" />
    <Property Type="String" Name="Size" MaxLength="5" FixedLength="false"
              Unicode="true" />
    <Property Type="String" Name="SizeUnitMeasureCode" MaxLength="3"
              FixedLength="true" Unicode="true" />
    <Property Type="String" Name="WeightUnitMeasureCode" MaxLength="3"
              FixedLength="true" Unicode="true" />
    <Property Type="Decimal" Name="Weight" Precision="8" Scale="2" />
    <Property Type="Int32" Name="DaysToManufacture" Nullable="false" />
    <Property Type="String" Name="ProductLine" MaxLength="2"
              FixedLength="true" Unicode="true" />
    <Property Type="String" Name="Class" MaxLength="2" FixedLength="true"
              Unicode="true" />
    <Property Type="String" Name="Style" MaxLength="2" FixedLength="true"
              Unicode="true" />
    <Property Type="Int32" Name="ProductSubcategoryID" />
    <Property Type="Int32" Name="ProductModelID" />
    <Property Type="DateTime" Name="SellStartDate" Nullable="false" />
    <Property Type="DateTime" Name="SellEndDate" />
    <Property Type="Guid" Name="rowguid" Nullable="false" />
    <Property Type="DateTime" Name="ModifiedDate" Nullable="false" />
  </EntityType>
  <EntityType Name="DiscontinuedProduct" BaseType="AdventureWorksModel.Product" >
    <Property Type="DateTime" Name="DiscontinuedDate" />
  </EntityType>
</Schema>

So definieren Sie die Zuordnung zwischen dem konzeptionellen Modell und dem Speichermodell

  1. Fügen Sie dem Projekt die folgende XML-Datei hinzu, und geben Sie ihr den Namen AdventureWorks.msl. Beachten Sie Folgendes:

    • Die Zuordnung für die Entitätstypen Product und DiscontinuedProduct wird im gleichen EntitySetMapping-Element definiert.

    • Die geerbten Eigenschaften für das DiscontinuedProduct werden den entsprechenden Spalten in der zugrunde liegenden Datenbanktabelle zugeordnet.

    • Die Syntax IsTypeOf wird verwendet, um den Typ des abgeleiteten DiscontinuedProduct-Typs anzugeben.

    • Die Diskriminatorspalte MakeFlag wird für die einzelnen Entitätstypen in der Hierarchie in einem Condition-Element zugeordnet.

    <?xml version="1.0" encoding="utf-8" ?>
    <Mapping Space="C-S" xmlns="https://schemas.microsoft.com/ado/2008/09/mapping/cs">
      <EntityContainerMapping StorageEntityContainer="AdventureWorksModelStoreContainer"
                              CdmEntityContainer="AdventureWorksEntities">
        <EntitySetMapping Name="Products">
          <EntityTypeMapping TypeName="AdventureWorksModel.Product">
            <MappingFragment StoreEntitySet="Product">
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
              <ScalarProperty Name="ModifiedDate" ColumnName="ModifiedDate" />
              <ScalarProperty Name="rowguid" ColumnName="rowguid" />
              <ScalarProperty Name="SellEndDate" ColumnName="SellEndDate" />
              <ScalarProperty Name="SellStartDate" ColumnName="SellStartDate" />
              <ScalarProperty Name="ProductModelID" ColumnName="ProductModelID" />
              <ScalarProperty Name="ProductSubcategoryID" ColumnName="ProductSubcategoryID" />
              <ScalarProperty Name="Style" ColumnName="Style" />
              <ScalarProperty Name="Class" ColumnName="Class" />
              <ScalarProperty Name="ProductLine" ColumnName="ProductLine" />
              <ScalarProperty Name="DaysToManufacture" ColumnName="DaysToManufacture" />
              <ScalarProperty Name="Weight" ColumnName="Weight" />
              <ScalarProperty Name="WeightUnitMeasureCode" ColumnName="WeightUnitMeasureCode" />
              <ScalarProperty Name="SizeUnitMeasureCode" ColumnName="SizeUnitMeasureCode" />
              <ScalarProperty Name="Size" ColumnName="Size" />
              <ScalarProperty Name="ListPrice" ColumnName="ListPrice" />
              <ScalarProperty Name="StandardCost" ColumnName="StandardCost" />
              <ScalarProperty Name="ReorderPoint" ColumnName="ReorderPoint" />
              <ScalarProperty Name="SafetyStockLevel" ColumnName="SafetyStockLevel" />
              <ScalarProperty Name="Color" ColumnName="Color" />
              <ScalarProperty Name="FinishedGoodsFlag" ColumnName="FinishedGoodsFlag" />
              <ScalarProperty Name="ProductNumber" ColumnName="ProductNumber" />
              <ScalarProperty Name="Name" ColumnName="Name" />
              <Condition ColumnName="MakeFlag" Value="0" />
            </MappingFragment>
          </EntityTypeMapping>
          <EntityTypeMapping TypeName="IsTypeOf(AdventureWorksModel.DiscontinuedProduct)">
            <MappingFragment StoreEntitySet="Product">
              <ScalarProperty Name="ModifiedDate" ColumnName="ModifiedDate" />
              <ScalarProperty Name="rowguid" ColumnName="rowguid" />
              <ScalarProperty Name="SellEndDate" ColumnName="SellEndDate" />
              <ScalarProperty Name="SellStartDate" ColumnName="SellStartDate" />
              <ScalarProperty Name="ProductModelID" ColumnName="ProductModelID" />
              <ScalarProperty Name="ProductSubcategoryID" ColumnName="ProductSubcategoryID" />
              <ScalarProperty Name="Style" ColumnName="Style" />
              <ScalarProperty Name="Class" ColumnName="Class" />
              <ScalarProperty Name="ProductLine" ColumnName="ProductLine" />
              <ScalarProperty Name="DaysToManufacture" ColumnName="DaysToManufacture" />
              <ScalarProperty Name="Weight" ColumnName="Weight" />
              <ScalarProperty Name="WeightUnitMeasureCode" ColumnName="WeightUnitMeasureCode" />
              <ScalarProperty Name="SizeUnitMeasureCode" ColumnName="SizeUnitMeasureCode" />
              <ScalarProperty Name="Size" ColumnName="Size" />
              <ScalarProperty Name="ListPrice" ColumnName="ListPrice" />
              <ScalarProperty Name="StandardCost" ColumnName="StandardCost" />
              <ScalarProperty Name="ReorderPoint" ColumnName="ReorderPoint" />
              <ScalarProperty Name="SafetyStockLevel" ColumnName="SafetyStockLevel" />
              <ScalarProperty Name="Color" ColumnName="Color" />
              <ScalarProperty Name="FinishedGoodsFlag" ColumnName="FinishedGoodsFlag" />
              <ScalarProperty Name="ProductNumber" ColumnName="ProductNumber" />
              <ScalarProperty Name="Name" ColumnName="Name" />
              <ScalarProperty Name="ProductID" ColumnName="ProductID" />
              <ScalarProperty Name="DiscontinuedDate" ColumnName="DiscontinuedDate" />
              <Condition ColumnName="MakeFlag" Value="1" />
            </MappingFragment>
          </EntityTypeMapping>
        </EntitySetMapping>
      </EntityContainerMapping>
    </Mapping>
    

Siehe auch

Aufgaben

Gewusst wie: Definieren eines Modells mit einer 'Tabelle pro Typ'-Vererbung (Entity Framework)

Weitere Ressourcen

Definieren von erweiterten Datenmodellen (Entity Framework-Aufgaben)
CSDL-, SSDL- und MSL-Spezifikationen