HOW TO:使用每個階層的資料表繼承來定義模型 (Entity Framework)

本主題描述如何手動建立概念模型,該模型具有單表 (Table-Per Hierarchy) 繼承。 單表 (Table-Per Hierarchy) 繼承會使用一個資料庫資料表來維護繼承階層架構中所有實體類型的資料。

Bb738443.note(zh-tw,VS.100).gif注意:
建議您使用 ADO.NET Entity Data Model Tools來定義具有一類一表 (Table-Per-Type) 繼承的模型。如需詳細資訊,請參閱Walkthrough: Mapping Inheritance - Table-per-Hierarchy

如果要手動定義具有單表 (Table-Per Hierarchy) 繼承的模型,基本步驟如下:

  1. 在概念模型中定義一個實體集,其中包含基底實體類型和衍生型別。 如需詳細資訊,請參閱 EntitySet 項目 (CSDL)

  2. 使用 BaseType 屬性來定義概念模型中的衍生實體類型,並且針對衍生型別單獨定義非繼承屬性。 如需詳細資訊,請參閱 EntityType 項目 (CSDL)

  3. 從基礎資料庫資料表中選擇資料行,這個資料行的值將用來區分基底類型和衍生型別。 例如,如果 Employee 資料表具有整數值的 EmployeeType 資料行,這個資料行的值可用來區分 Employee 基底實體類型何時為下列其中一個衍生實體類型:HourlyEmployeeSalariedEmployee。 如需詳細資訊,請參閱下列範例。

    鑑別子資料行會當做條件的一部分來對應,所以階層架構中的任何實體類型可能不會有任何對應的屬性。 這個規則的例外情形是當條件使用 Is NullIs Not Null 比較時。 在此情況下,鑑別子資料行可以在實體類型上擁有對應的屬性。

    如果鑑別子資料行可以有兩個以上的值 (例如整數類型),此資料行必須可為 Null 或是擁有預設值。 這樣可確保當建立新的型別並儲存到資料庫時,資料行可以為 Null 或是具有某個值。

    必須使用條件,才能對應階層架構中的每一個衍生型別,而且可使用條件來對應基底類型。 如果基底類型為抽象的,則不允許對應或條件。

  4. 使用對應規格語言 (MSL),在相同的 EntitySetMapping 項目中對應基底實體類型和衍生型別。 將繼承屬性對應至資料表資料行 (如果適用的話)。 設定衍生型別的 TypeName 屬性值時,請使用 IsTypeOf 語法。 使用對應條件可區分階層架構中的型別。 如需詳細資訊,請參閱 EntitySetMapping 項目 (MSL)Condition 元素 (MSL)

下列範例假設您已經安裝 School 範例資料庫,而且已經手動設定您的專案使用 Entity Framework 。 如需詳細資訊,請參閱建立 School 範例資料庫 (Entity Framework 快速入門)設定 Entity Framework (Entity Framework 工作)

若要建立儲存體模型

  1. 將下列 XML 檔案加入至專案,並將它命名為 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>
    

若要建立概念模型

  1. 將下列 XML 檔案加入至專案,並將它命名為 AdventureWorks.csdl。 請注意以下各點:

    • 僅針對兩個實體類型定義一個實體集 ProductsProductDiscontinuedProduct

    • DiscontinuedProduct 實體類型是 BaseType 屬性在它的定義中所指示的衍生型別。

    • DiscontinuedProduct 實體類型上定義的屬性只能是非繼承的屬性。

    • 儲存體模型中的 MakeFlag 資料行 (請參閱上述的 AdventureWorks.ssdl 檔案) 不會在基底類型或衍生型別上當做屬性出現。 此資料行的值當做條件的一部分來對應時,將會用來區分階層架構中的型別 (請參閱底下的 AdventureWorks.msl 檔案)。

    Bb738443.note(zh-tw,VS.100).gif注意:
    如果資料行用於 Is NullIs Not Null 條件中,則對應的屬性可以出現在實體類型上。

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

若要定義概念模型與儲存體模型之間的對應

  1. 將下列 XML 檔案加入至專案,並將它命名為 AdventureWorks.msl。 請注意以下各點:

    • ProductDiscontinuedProduct 實體類型的對應會定義在相同的 EntitySetMapping 項目中。

    • DiscontinuedProduct 的繼承屬性會對應至基礎資料庫資料表的對應資料行。

    • IsTypeOf 語法是用來指示衍生 DiscontinuedProduct 型別的型別。

    • 鑑別子資料行 MakeFlag 會在階層架構中每一個實體類型的 Condition 項目中對應。

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

另請參閱

工作

HOW TO:使用一類一表 (Table-Per-Type) 繼承來定義模型 (Entity Framework)

其他資源

定義進階資料模型 (Entity Framework 工作)
CSDL、SSDL 和 MSL 規格