Compartir a través de


Herencia (EDM)

En Entity Data Model (EDM), la herencia permite que un tipo derivado extienda las características de otro tipo.

Generalmente, el modelo usado por una aplicación incluye varios tipos diferentes. Algunos tipos de entidad modelan los conceptos independientes, como los clientes y pedidos****, en una aplicación empresarial. Estos tipos de datos no comparten ningún miembro, pero hay otros que son más similares entre sí. Por ejemplo, considere los tipos customer y employee. Aunque estos tipos modelan conceptos diferentes, existe una similitud subyacente: ambos representan a las personas implicadas en las relaciones empresariales e incluyen propiedades para almacenar información como el nombre, la dirección y el número de teléfono.

La herencia de EDM permite que un tipo se derive de otro. Por ejemplo, Employee y Customer pueden heredarse ambos del tipo Contact. En este caso, Contact se conoce como tipo base. Employee y Customer se conocen como tipos derivados.

La herencia no tiene que detenerse en un único nivel: es posible que un tipo derivado sea el tipo base de otro tipo de entidad. Por ejemplo, Employee es un tipo base de Manager; Customer es un tipo base de PreferredCustomer, y así sucesivamente. De este modo se crean las jerarquías de herencia.

Al igual que Common Language Runtime (CLR), el sistema EDM sólo admite la herencia simple de tipos de datos. Un tipo de entidad sólo puede heredar directamente las propiedades de un supertipo.

Nota

Dado que el sistema EDM no implementa métodos, no se admite la herencia de métodos. En el EDM, los métodos auxiliares se implementan en clases parciales. Para obtener más información, vea Métodos auxiliares (EDM).

Ejemplos de herencia

El ejemplo siguiente muestra una especificación parcial del lenguaje de definición de esquemas conceptuales (CSDL, Conceptual Schema Definition Language) para la jerarquía de herencia descrita anteriormente.

  <EntityType Name="Contact">
    <Key>
      <PropertyRef Name="ContactId" />
    </Key>
    <Property Name="ContactId" Type="Int32" Nullable="false" />
    <Property Name="Name" Type="String" />
    <Property Name="Address" Type="Address" />
    <Property Name="Phone" Type="String" />
  </EntityType>

  <EntityType Name="Customer" BaseType="Contact">
    <Property Name="CustomerID" Type="String" />
    <Property Name="CompanyName" Type="String" />
  </EntityType>

  <EntityType Name="PreferredCustomer" BaseType="Customer">
    <Property Name="PreferenceCode" Type="String" />
    <Property Name="CreditLimit" Type="Decimal" />
  </EntityType>
  <!-- Similar Declarations for Employee and Manager -->

Uno de los propósitos de la herencia es compartir una estructura fundamental entre varios tipos. Otra razón para usar la herencia es la extensibilidad. Incluso una vez implementada en una aplicación una jerarquía de herencia, los programadores pueden extender los tipos a través de la herencia.

El concepto de polimorfismo o capacidad de sustitución de valores propio de la programación orientada a objetos depende de la herencia. Cada instancia de un tipo de datos derivado también es una instancia de su tipo base. Por ejemplo, si Manager se deriva de Employee, cada instancia de Manager también es una instancia de Employee. Al consultar todos los empleados (tipo base), también obtiene todos los directores (tipo derivado).

Para obtener más información sobre la herencia, vea Cómo definir un modelo con herencia de tabla por tipo y Cómo definir un modelo con herencia de tabla por jerarquía (Entity Framework).

Implementación de la herencia

En las tablas de bases de datos que almacenan los datos de una aplicación integrada en el modelo EDM se debe implementar una jerarquía de la herencia según se define en CSDL. Los tipos de una jerarquía de herencia pueden estructurarse de varios modos en las tablas de una base de datos.

En todas las implementaciones, la estructura de clave de los tipos base y derivado debe ser idéntica. Es decir, si un tipo Customer se deriva del tipo Person, tanto el tipo Customer como el tipo Person deben especificar la misma propiedad o propiedades clave.

En las implementaciones de la herencia que usan varias tablas, se asigna el mismo valor a la propiedad clave en más de una tabla para identificar los tipos derivados como instancias de los tipos antecesores.

En la especificación de asignaciones, las implementaciones de la herencia pueden usar el indicador IsTypeOf<T> de EntityTypeMapping con el fin de especificar que el tipo Customer también es un tipo del tipo base Person, por ejemplo. Además, hay un atributo BaseType de EntityType en los esquemas conceptual y de almacenamiento que se puede usar para designar el tipo base de una entidad derivada.

Modelo de tabla por jerarquía

La herencia basada en el modelo de tabla por jerarquía especifica varios tipos en la jerarquía con la misma tabla de base de datos. En este modelo, una condición explícita en la especificación de asignaciones identifica el tipo de la jerarquía de la herencia.

En la tabla se incluye una columna de discriminación para distinguir cada tipo, y la condición hace referencia a un valor asignado de la columna para cada tipo. Por ejemplo, la condición puede especificar que el valor de la columna EntityType es igual a P para el tipo Person o a C para el tipo Customer.

El ejemplo de asignación siguiente muestra la asignación condicional de los tipos Customer y Person.

<?xml version="1.0" encoding="utf-8"?>
<Mapping Space="C-S"
    xmlns:cdm="urn:schemas-microsoft-com:windows:storage:mapping:CS"
    xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">

  <EntityContainerMapping>
    <EntitySetMapping Name="CCustomer1">
      <EntityTypeMapping TypeName="CNorthwind.CCustomer">
        <MappingFragment StoreEntitySet="SParty1">
          <EntityKey>
            <ScalarProperty Name="PartyID" ColumnName="PartyID" />
          </EntityKey>
          <ScalarProperty Name="PartyName" ColumnName="PartyName" />
          <ScalarProperty Name="PartyTitle" ColumnName="Title" />
          <ScalarProperty Name="ContactName" ColumnName="ContactName" />
          <Condition Value="C" ColumnName="EntityType" />
        </MappingFragment>
      </EntityTypeMapping>
    </EntitySetMapping>

    <EntitySetMapping Name="CSupplier1">
      <EntityTypeMapping TypeName="CNorthwind.CSupplier">
        <MappingFragment StoreEntitySet="SParty1">
          <EntityKey>
            <ScalarProperty Name="PartyID" ColumnName="PartyID" />
          </EntityKey>
          <ScalarProperty Name="PartyName" ColumnName="PartyName" />
          <ScalarProperty Name="PartyTitle" ColumnName="Title" />
          <ScalarProperty Name="HomePage" ColumnName="HomePage" />
          <Condition Value="S" ColumnName="EntityType" />
        </MappingFragment>
      </EntityTypeMapping>
    </EntitySetMapping>

  </EntityContainerMapping>

</Mapping>

Modelo de tabla por tipo

En la herencia basada en el modelo de tabla por tipo, el tipo base o el tipo antecesor se almacena en una tabla, pero se usan tablas adicionales para los tipos derivados. Los campos específicos de los tipos derivados sólo aparecen en las tablas que representan tipos derivados. La asignación de las entidades en este modelo de herencia abarca varias tablas físicas. La presencia o ausencia de una fila en una tabla distingue los tipos en la jerarquía. El mismo valor de clave se asigna a la propiedad de la clave en todas las tablas.

El atributo BaseType de EntityType se puede usar en los esquemas conceptual y de almacenamiento para indicar la herencia del tipo base. El indicador IsTypeOf<T> en la especificación de asignaciones se puede usar para especificar el tipo base y eliminar la sintaxis de la asignación duplicada.

El ejemplo de asignación siguiente muestra dos asignaciones independientes para los tipos Customer y Person. Los atributos ****TypeName de los elementos EntityTypeMapping distinguen los tipos Person y Customer. Hay una tabla para cada tipo. El tipo de entidad Customer y la tabla contienen la propiedad NumYears y la columna que no se incluye en el tipo base.

<?xml version="1.0" encoding="utf-8"?>
<Mapping Space="C-S" 
    xmlns:cdm="urn:schemas-microsoft-com:windows:storage:mapping:CS"
    xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">

  <EntityContainerMapping EntityContainerName="CNorthwind.LOBData">
    <EntitySetMapping Name="Person1">
      <EntityTypeMapping TypeName="CNorthwind.Person">
        <MappingFragment StoreEntitySet="Person">
          <ScalarProperty Name="PersonID" ColumnName="PersonID" />
          <ScalarProperty Name="Name" ColumnName="Name" />
        </MappingFragment>
      </EntityTypeMapping>
      <EntityTypeMapping TypeName="CNorthwind.Customer">
        <MappingFragment StoreEntitySet="Customer">
          <ScalarProperty Name="PersonID" ColumnName="PersonID" />
          <ScalarProperty Name="Name" ColumnName="Name" />
          <ScalarProperty Name="NumYears" ColumnName="NumYears" />
        </MappingFragment>
      </EntityTypeMapping>
    </EntitySetMapping>
  </EntityContainerMapping>

</Mapping>

Vea también

Tareas

Cómo definir un modelo con herencia de tabla por tipo (Entity Framework)
Cómo definir un modelo con herencia de tabla por jerarquía (Entity Framework)

Conceptos

Tipos del Entity Data Model
Métodos auxiliares (EDM)
Herencia de Entity Data Model (escenarios de las aplicaciones)