Compartir a través de


Cómo personalizar un modelo Entity Data Model para trabajar con objetos personalizados (Entity Framework)

Si se desea usar clases de datos personalizadas con un Entity Data Model (EDM), los tipos de entidad y las propiedades definidas en el archivo del lenguaje de definición de esquemas conceptuales (CSDL, Conceptual Schema Definition Language) deben coincidir con las clases de datos personalizadas. Las herramientas de Entity Framework generan un conjunto de archivos de asignación en el que los tipos de entidad y los conjuntos de entidades del archivo de CSDL coinciden con las tablas de la base de datos. El proceso para actualizar estos archivos de asignaciones para las clases de datos personalizadas es el siguiente:

  1. Se actualiza el archivo de CSDL para que coincida con las clases de datos personalizadas.

  2. Se actualiza la asignación en el archivo del lenguaje de especificación de asignaciones (MSL).

  3. Se actualiza el archivo del lenguaje de definición de esquemas de almacenamiento (SSDL), si es necesario.

  4. Se validan los archivos de asignaciones actualizados.

  5. Se impide que Visual Studio genere el nivel de objetos.

Para ejecutar el ejemplo de este tema, debe haber usado ya la utilidad Generador de EDM (EdmGen.exe) o el Asistente para Entity Data Model para generar los archivos de asignación del modelo EDM. Para obtener más información, vea Cómo usar EdmGen.exe para generar un modelo Entity Data Model (Entity Framework). Si está utilizando Entity Data Model Designer en Visual Studio, también debe deshabilitar la generación de capa de objeto basada en el archivo CSDL actualizado. De lo contrario, tendrá que duplicar las clases de datos en el proyecto.

Para actualizar el archivo de CSDL de modo que refleje los objetos de datos personalizados

  1. Abra el archivo de CSDL en Visual Studio o en notepad.exe.

  2. Cambie el nombre de los elementos EntityType y EntitySet para reflejar los nombres de las clases de datos personalizadas.

  3. Quite los elementos EntityType y EntitySet de una entidad que no tenga una clase de datos personalizada correspondiente.

  4. Cambie el nombre de los elementos Property de cada tipo para que coincida con el nombre de las propiedades en la clase de datos personalizada.

  5. Quite los elementos Property de las propiedades que no existan en la clase de datos personalizada.

  6. Guarde los cambios en el archivo de CSDL.

Para actualizar el archivo de MSL para asignar objetos de datos personalizados a objetos del origen de datos

  1. Abra el archivo de MSL en Visual Studio o en notepad.exe.

  2. Cambie el nombre del elemento EntitySetMapping y del atributo TypeName para reflejar los nombres de las clases personalizadas.

  3. Quite el elemento EntitySetMapping de las entidades que no tengan una clase de datos personalizada correspondiente.

  4. Cambie el nombre de los elementos ScalarProperty de cada tipo para que coincida con el de las propiedades en la clase de datos personalizada.

  5. Quite el elemento ScalarProperty de las propiedades que no existan en la clase de datos personalizada.

  6. Cambie el nombre del elemento EndProperty de AssociationSetMapping para reflejar los nombres de las clases personalizadas.

  7. Cambie el nombre de los elementos ScalarProperty de cada AssociationSetMapping para que coincida con el de las propiedades en la clase de datos personalizada.

    Nota

    No cambie ninguna de las propiedades ColumnName.

  8. Quite el elemento AssociationSetMapping de las asociaciones entre las entidades que no existan en las clases de datos personalizadas.

  9. Guarde los cambios en el archivo de MSL.

Para actualizar el archivo de SSDL y quitar las entidades que no existan en las clases de datos personalizadas

  1. Abra el archivo de SSDL en Visual Studio o en notepad.exe.

  2. Quite los elementos EntityType de las entidades que no estén asignadas a clases de datos personalizadas.

  3. Quite los elementos ScalarProperty de las propiedades que no estén asignadas a propiedades de clases de datos personalizadas.

  4. Guarde los cambios en el archivo de SSDL.

Para validar los archivos de asignaciones actualizados

  1. Ejecute la utilidad EdmGen.exe en el directorio que contenga los archivos de asignación. Use el siguiente comando:

    %windir%\Microsoft.NET\Framework\v3.5\edmgen.exe /mode:ValidateArtifacts  
    /inssdl:.\YourModel.ssdl /inmsl:.\YourModel.msl /incsdl:.\YourModel.csdl 
    
    Nota

    Quite los saltos de línea y reemplace YourModel por el nombre que se use para los archivos de asignaciones.

  2. Revise la salida y repare los errores de validación.

Para volver a generar, guardar y quitar el código de objetos generados automáticamente

  1. En el Explorador de soluciones, en Visual Studio, haga clic con el botón secundario en el archivo de CSDL**y seleccione Ejecutar herramienta personalizada.

    De este modo se vuelve a generar el nivel de objetos según el archivo de CSDL modificado.

  2. Expanda el nodo del archivo de CSDL, abra el archivo del diseñador y guárdelo con un nombre diferente.

    De este modo se guarda el archivo del nivel de objetos generado automáticamente. El código de este archivo se usa en el tema Cómo usar Servicios de objeto con objetos personalizados (Entity Framework).

  3. Excluya el archivo del diseñador del proyecto.

  4. Seleccione el archivo de CSDL y borre el valor Herramienta personalizada de la ventana Propiedades.

    De este modo se impide que el archivo del nivel de objetos se regenere. Para generar este archivo en el futuro, escriba EntityModelCodeGenerator como Herramienta personalizada en la ventana Propiedades y repita el paso 1.

Ejemplo

El siguiente archivo de CSDL se ha personalizado para que sea compatible con las clases de datos personalizadas Orders y LineItem.

<Schema Namespace="Microsoft.Samples.Edm" Alias="Self" xmlns="https://schemas.microsoft.com/ado/2006/04/edm">
  <EntityContainer Name="SalesOrdersEntities">
    <EntitySet Name="LineItem" EntityType="Microsoft.Samples.Edm.LineItem" />
    <EntitySet Name="Order" EntityType="Microsoft.Samples.Edm.Order" />
    <AssociationSet Name="FK_LineItem_Order_OrderId" Association="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId">
      <End Role="Order" EntitySet="Order" />
      <End Role="LineItem" EntitySet="LineItem" />
    </AssociationSet>
  </EntityContainer>
  <EntityType Name="LineItem">
    <Key>
      <PropertyRef Name="LineItemId" />
    </Key>
    <Property Name="LineItemId" Type="Int32" Nullable="false" />
    <Property Name="TrackingNumber" Type="String" MaxLength="25" />
    <Property Name="Quantity" Type="Int16" Nullable="false" />
    <Property Name="Product" Type="Int32" Nullable="false" />
    <Property Name="Price" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="Discount" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <NavigationProperty Name="Order" Relationship="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" 
                        FromRole="LineItem" ToRole="Order" />
  </EntityType>
  <EntityType Name="Order">
    <Key>
      <PropertyRef Name="OrderId" />
    </Key>
    <Property Name="OrderId" Type="Int32" Nullable="false" />
    <Property Name="OrderDate" Type="DateTime" Nullable="false" />
    <Property Name="DueDate" Type="DateTime" Nullable="false" />
    <Property Name="ShipDate" Type="DateTime" />
    <Property Name="Status" Type="Byte" Nullable="false" />
    <Property Name="Customer" Type="Int32" Nullable="false" />
    <Property Name="SubTotal" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="TaxAmt" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="Freight" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="ExtendedInfo" Type="Self.OrderInfo" Nullable="false" />
    <NavigationProperty Name="LineItem" Relationship="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" 
                        FromRole="Order" ToRole="LineItem" />
  </EntityType>
    <ComplexType Name="OrderInfo">
        <Property Name="OrderNumber" Type="String" Nullable="false" MaxLength="25" />
        <Property Name="PurchaseOrder" Type="String" MaxLength="25" />
        <Property Name="AccountNumber" Type="String" MaxLength="15" />
        <Property Name="Comment" Type="String" MaxLength="128" />
    </ComplexType>
  <Association Name="FK_LineItem_Order_OrderId">
    <End Role="Order" Type="Microsoft.Samples.Edm.Order" Multiplicity="1" />
    <End Role="LineItem" Type="Microsoft.Samples.Edm.LineItem" Multiplicity="*" />
  </Association>
</Schema>

El siguiente archivo de MSL se ha personalizado para asignar las clases de datos personalizadas Orders y LineItem a las tablas SalesOrderHeader y SalesOrderDetail de la base de datos de AdventureWorks.

<Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
  <EntityContainerMapping StorageEntityContainer="Sales" CdmEntityContainer="SalesOrdersEntities">
    <EntitySetMapping Name="LineItem" StoreEntitySet="SalesOrderDetail" TypeName="Microsoft.Samples.Edm.LineItem">
      <ScalarProperty Name="LineItemId" ColumnName="SalesOrderDetailID" />
      <ScalarProperty Name="TrackingNumber" ColumnName="CarrierTrackingNumber" />
      <ScalarProperty Name="Quantity" ColumnName="OrderQty" />
      <ScalarProperty Name="Product" ColumnName="ProductID" />
      <ScalarProperty Name="Price" ColumnName="UnitPrice" />
      <ScalarProperty Name="Discount" ColumnName="UnitPriceDiscount" />
    </EntitySetMapping>
    <EntitySetMapping Name="Order" StoreEntitySet="SalesOrderHeader" TypeName="Microsoft.Samples.Edm.Order">
      <ScalarProperty Name="OrderId" ColumnName="SalesOrderID" />
      <ScalarProperty Name="OrderDate" ColumnName="OrderDate" />
      <ScalarProperty Name="DueDate" ColumnName="DueDate" />
      <ScalarProperty Name="ShipDate" ColumnName="ShipDate" />
      <ScalarProperty Name="Status" ColumnName="Status" />
      <ScalarProperty Name="Customer" ColumnName="CustomerID" />
      <ScalarProperty Name="SubTotal" ColumnName="SubTotal" />
      <ScalarProperty Name="TaxAmt" ColumnName="TaxAmt" />
      <ScalarProperty Name="Freight" ColumnName="Freight" />
      <ComplexProperty Name ="ExtendedInfo" TypeName ="Microsoft.Samples.Edm.OrderInfo">
        <ScalarProperty Name="OrderNumber" ColumnName="SalesOrderNumber" />
        <ScalarProperty Name="PurchaseOrder" ColumnName="PurchaseOrderNumber" />
        <ScalarProperty Name="AccountNumber" ColumnName="AccountNumber" />
        <ScalarProperty Name="Comment" ColumnName="Comment" />
      </ComplexProperty>
    </EntitySetMapping>
    <AssociationSetMapping Name="FK_LineItem_Order_OrderId" TypeName="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" StoreEntitySet="SalesOrderDetail">
      <EndProperty Name="Order">
        <ScalarProperty Name="OrderId" ColumnName="SalesOrderID" />
      </EndProperty>
      <EndProperty Name="LineItem">
        <ScalarProperty Name="LineItemId" ColumnName="SalesOrderDetailID" />
      </EndProperty>
      <Condition ColumnName="SalesOrderID" IsNull="false" />
    </AssociationSetMapping>
  </EntityContainerMapping>
</Mapping>

El siguiente archivo de SSDL se ha personalizado para que sea compatible con las clases de datos personalizadas Orders y LineItem usando las tablas SalesOrderHeader y SalesOrderDetail de la base de datos AdventureWorks.

<Schema Namespace="Microsoft.Samples.Edm.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns="https://schemas.microsoft.com/ado/2006/04/edm/ssdl">
  <EntityContainer Name="Sales">
    <EntitySet Name="SalesOrderDetail" EntityType="Microsoft.Samples.Edm.Store.SalesOrderDetail" />
    <EntitySet Name="SalesOrderHeader" EntityType="Microsoft.Samples.Edm.Store.SalesOrderHeader" />
    <AssociationSet Name="FK_LineItem_Orders_OrderId" Association="Microsoft.Samples.Edm.Store.FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
      <End Role="SalesOrderHeader" EntitySet="SalesOrderHeader" />
      <End Role="SalesOrderDetail" EntitySet="SalesOrderDetail" />
    </AssociationSet>
  </EntityContainer>
  <EntityType Name="SalesOrderDetail">
    <Key>
      <PropertyRef Name="SalesOrderDetailID" />
    </Key>
    <Property Name="SalesOrderID" Type="int" Nullable="false" />
    <Property Name="SalesOrderDetailID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="CarrierTrackingNumber" Type="nvarchar" MaxLength="25" />
    <Property Name="OrderQty" Type="smallint" Nullable="false" />
    <Property Name="ProductID" Type="int" Nullable="false" />
    <Property Name="UnitPrice" Type="money" Nullable="false" />
    <Property Name="UnitPriceDiscount" Type="money" Nullable="false" />
  </EntityType>
  <EntityType Name="SalesOrderHeader">
    <Key>
      <PropertyRef Name="SalesOrderID" />
    </Key>
    <Property Name="SalesOrderID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="OrderDate" Type="datetime" Nullable="false" />
    <Property Name="DueDate" Type="datetime" Nullable="false" />
    <Property Name="ShipDate" Type="datetime" />
    <Property Name="Status" Type="tinyint" Nullable="false" />
    <Property Name="SalesOrderNumber" Type="nvarchar" Nullable="false" StoreGeneratedPattern="Computed" MaxLength="25" />
    <Property Name="PurchaseOrderNumber" Type="nvarchar" MaxLength="25" />
    <Property Name="AccountNumber" Type="nvarchar" MaxLength="15" />
    <Property Name="CustomerID" Type="int" Nullable="false" />
    <Property Name="SubTotal" Type="money" Nullable="false" />
    <Property Name="TaxAmt" Type="money" Nullable="false" />
    <Property Name="Freight" Type="money" Nullable="false" />
    <Property Name="Comment" Type="nvarchar" MaxLength="128" />
  </EntityType>
  <Association Name="FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
    <End Role="SalesOrderHeader" Type="Microsoft.Samples.Edm.Store.SalesOrderHeader" Multiplicity="1" />
    <End Role="SalesOrderDetail" Type="Microsoft.Samples.Edm.Store.SalesOrderDetail" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="SalesOrderHeader">
        <PropertyRef Name="SalesOrderID" />
      </Principal>
      <Dependent Role="SalesOrderDetail">
        <PropertyRef Name="SalesOrderID" />
      </Dependent>
    </ReferentialConstraint>
  </Association>
</Schema>

Vea también

Conceptos

Personalizar objetos (Entity Framework)

Otros recursos

Especificación de asignaciones y esquemas (Entity Framework)
Trabajar con objetos personalizados (tareas de Entity Framework)