Compatibilidad con los procedimientos almacenados (Entity Framework)

El Entity Data Model (EDM) admite procedimientos almacenados para la recuperación y modificación de datos. Los procedimientos almacenados se pueden usar para recuperar, actualizar y eliminar los datos.

Muchas aplicaciones de base de datos se basan en los procedimientos almacenados para proporcionar las ventajas siguientes:

  • Seguridad. A los usuarios de la base de datos se les puede denegar el acceso directo a las tablas u otros objetos de la base de datos. Los administradores de bases de datos sólo necesitan conceder permisos de ejecución en los procedimientos almacenados para crear puntos de entrada únicos de acceso a los datos. Esto reduce significativamente la superficie de ataque para los ataques de inyección SQL. Los parámetros de entrada y salida configurados para utilizar los valores predeterminados habilitan la validación estricta de parámetros. El código de la validación en los procedimientos almacenados puede limitar las acciones disponibles.

  • Encapsulación. La lógica de datos complejos, las transacciones explícitas y otras operaciones de base de datos se pueden escribir una vez en el código de los procedimientos almacenados y ejecutar desde varias aplicaciones cliente. Los errores, excepciones e infracciones de la simultaneidad se pueden controlar desde el código del servidor, reduciendo el número de viajes de ida y vuelta desde las aplicaciones cliente. El código de los procedimientos almacenados se puede modificar sin afectar a las aplicaciones cliente siempre que la firma del procedimiento almacenado permanezca inalterada.

  • Previsibilidad. Los administradores de bases de datos deben asegurarse con frecuencia de que las aplicaciones cliente no emiten consultas ineficaces que pueden afectar adversamente al rendimiento del servidor. Las consultas en los procedimientos almacenados se pueden ajustar individualmente para generar planes de ejecución aceptables. Además del ajuste, los procedimientos almacenados bien escritos simplifican la solución de problemas del servidor como los bloqueos e interbloqueos.

  • Rendimiento. En algunas situaciones, el uso de procedimientos almacenados puede producir mejoras en el rendimiento. Los motores de base de datos modernos generalmente tratan las instrucciones SQL con la misma eficacia que las instrucciones de los procedimientos almacenados; los administradores de bases de datos mantienen más control sobre el rendimiento exigiendo el uso de procedimientos almacenados.

Los procedimientos almacenados que devuelven datos se llaman desde las funciones con nombre en el modelo de objetos EDM. Los procedimientos almacenados que actualizan datos se asignan a las entidades y asociaciones, y se llaman implícitamente cuando las operaciones que definen usan los métodos generados por el sistema, en el caso de que no se hayan implementado y asignado procedimientos almacenados.

En este tema se describen los procedimientos almacenados utilizados para actualizar los datos a través de las asignaciones especificadas en el elemento de esquema ModificationFunctionMapping. Los procedimientos almacenados que recuperan datos utilizan el elemento FunctionImportMapping. Para conseguir un tutorial sobre los procedimientos almacenados que recuperan datos pero que no los cambian, vea Cómo definir un modelo con un procedimiento almacenado (Entity Framework).

Otro escenario que se puede administrar mediante procedimientos almacenados es la inserción o eliminación de una instancia de una asociación entre entidades existentes. La asignación de procedimientos almacenados a estas operaciones se describe en Asignar conjuntos de asociaciones a procedimientos almacenados (Entity Framework).

De forma predeterminada, Entity Framework realiza directamente las operaciones con las tablas de base de datos según las asignaciones entre los esquemas de almacenamiento y conceptual. Al configurar Entity Framework para utilizar procedimientos almacenados con el fin de actualizar los datos, se requieren modificaciones en los esquemas de asignación y almacenamiento.

La tabla siguiente contiene vínculos a los temas que explican el uso de procedimientos almacenados en diversos escenarios admitidos por el EDM.

Operación Requisitos de SSDL Requisitos de MSL Requisitos de CSDL

Ejecute una consulta que devuelva objetos de entidad. Para obtener más información, vea Cómo definir un modelo con un procedimiento almacenado (Entity Framework).

Agregue un elemento Function dentro del elemento Schema del archivo del modelo de almacenamiento. Este elemento hace referencia a un procedimiento almacenado que devuelve un tipo de entidad.

Agregue un elemento FunctionImportMapping en el elemento EntityContainerMapping del archivo del modelo conceptual.

Agregue un elemento FunctionImport en el elemento EntityContainer del archivo del modelo conceptual.

Los procedimientos almacenados se utilizan para insertar, actualizar y eliminar los datos de la entidad. Para obtener más información, vea Cómo definir un modelo con procedimientos almacenados de modificación (Entity Framework).

Agregue elementos Function dentro del elemento Schema del archivo del modelo de almacenamiento. Haga esto una vez por cada procedimiento almacenado de inserción, actualización o eliminación.

Agregue un elemento ModificationFunctionMapping en el elemento EntityTypeMapping para el tipo de entidad. Este elemento debe definir los elementos InsertFunction, DeleteFunction y UpdateFunction para los procedimientos almacenados de inserción, actualización o eliminación. Cuando la entidad tiene relaciones, un elemento AssociationEnd especifica la asociación.

Ninguna.

Los procedimientos almacenados se utilizan para crear o eliminar relaciones de varios a varios entre los tipos de entidad, que se implementan en el origen de datos utilizando una tabla de vínculo. Para obtener más información, vea Asignar conjuntos de asociaciones a procedimientos almacenados (Entity Framework).

Agregue elementos Function dentro del elemento Schema del archivo del modelo de almacenamiento. Haga esto una vez por cada procedimiento almacenado que cree o elimine relaciones en el origen de datos.

Agregue un elemento ModificationFunctionMapping en el elemento AssociationSetMapping para la asociación. Este elemento debe definir los elementos DeleteFunction e InsertFunction para los procedimientos almacenados que crean y eliminan relaciones para esta asociación.

Ninguna.

Modificaciones de datos y procedimientos almacenados

Los procedimientos almacenados utilizados para la modificación de datos reemplazan a los métodos generados por Entity Framework. A los procedimientos almacenados se les llama implícitamente, de modo que no se requiere ningún cambio en el EDM definido en el esquema conceptual o en el código de aplicación existente.

CSDL

El segmento del lenguaje de definición de esquemas conceptuales (CSDL) siguiente define una entidad SalesOrderHeader y una entidad SalesOrderDetail. Ambos tipos están basados en la base de datos de ejemplo de AdventureWorks que se incluye con SQL Server 2005 y SQL Server 2008. No es necesario realizar ninguna modificación del esquema CSDL con el fin de usar los procedimientos almacenados para modificar los datos del EDM, pero el esquema CSDL se muestra aquí por integridad. Este esquema omite algunas definiciones de propiedades por brevedad. El esquema completo se puede encontrar en el ejemplo de Modelo AdventureWorks Sales (EDM).

      <Schema Namespace="AdventureWorksModel" 
              Alias="Self" xmlns="https://schemas.microsoft.com/ado/2006/04/edm">
        <EntityContainer Name="AdventureWorksEntities">
          <EntitySet Name="AddressType" EntityType="AdventureWorksModel.AddressType" />
          <EntitySet Name="Contact" EntityType="AdventureWorksModel.Contact" />
          <EntitySet Name="Product" EntityType="AdventureWorksModel.Product" />
          <EntitySet Name="SalesOrderDetail" 
                     EntityType="AdventureWorksModel.SalesOrderDetail" />
          <EntitySet Name="SalesOrderHeader" 
                     EntityType="AdventureWorksModel.SalesOrderHeader" />
          <AssociationSet Name="FK_SalesOrderHeader_Contact_ContactID"
Association="AdventureWorksModel.FK_SalesOrderHeader_Contact_ContactID">
            <End Role="Contact" EntitySet="Contact" />
            <End Role="SalesOrderHeader" EntitySet="SalesOrderHeader" />
          </AssociationSet>
          <AssociationSet Name="FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID" 
Association="AdventureWorksModel.FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
            <End Role="SalesOrderHeader" EntitySet="SalesOrderHeader" />
            <End Role="SalesOrderDetail" EntitySet="SalesOrderDetail" />
          </AssociationSet>

        </EntityContainer>

        
        <EntityType Name="SalesOrderDetail">
          <Key>
            <PropertyRef Name="SalesOrderID" />
            <PropertyRef Name="SalesOrderDetailID" />
          </Key>
          <Property Name="SalesOrderID" Type="Int32" Nullable="false" />
          <Property Name="SalesOrderDetailID"
                             Type="Int32" Nullable="false" />
          <Property Name="CarrierTrackingNumber" Type="String" />
          <Property Name="OrderQty" Type="Int16" Nullable="false" />
          <Property Name="ProductID" Type="Int32" Nullable="false" />
          <Property Name="SpecialOfferID" Type="Int32" Nullable="false" />
          <Property Name="UnitPrice" Type="Decimal" Nullable="false" />
          <Property Name="UnitPriceDiscount"
                             Type="Decimal" Nullable="false" />
          <Property Name="LineTotal" Type="Decimal" Nullable="false" />
          <Property Name="rowguid" Type="Guid" Nullable="false" />
          <Property Name="ModifiedDate"
                             Type="DateTime" Nullable="false" />
          <NavigationProperty Name="SalesOrderHeader"
Relationship="AdventureWorksModel.FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID"
             FromRole="SalesOrderDetail" ToRole="SalesOrderHeader" />
        </EntityType>

        <EntityType Name="SalesOrderHeader">
          <Key>
            <PropertyRef Name="SalesOrderID" />
          </Key>
          <Property Name="SalesOrderID" Type="Int32" Nullable="false" />
          <Property Name="RevisionNumber" Type="Byte" 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="OnlineOrderFlag"
                        Type="Boolean" Nullable="false" />
          <Property Name="SalesOrderNumber"
                        Type="String" Nullable="false" />
          <Property Name="PurchaseOrderNumber" Type="String" />
          <Property Name="AccountNumber" Type="String" />
          <Property Name="CustomerID" Type="Int32" Nullable="false" />
          <Property Name="SalesPersonID" Type="Int32" />
          <Property Name="TerritoryID" Type="Int32" />
          <Property Name="BillToAddressID"
                        Type="Int32" Nullable="false" />
          <Property Name="ShipToAddressID"
                        Type="Int32" Nullable="false" />
          <Property Name="ShipMethodID" Type="Int32" Nullable="false" />
          <Property Name="CreditCardID" Type="Int32" />
          <Property Name="CreditCardApprovalCode" Type="String" />
          <Property Name="CurrencyRateID" Type="Int32" />
          <Property Name="SubTotal" Type="Decimal" Nullable="false" />
          <Property Name="TaxAmt" Type="Decimal" Nullable="false" />
          <Property Name="Freight" Type="Decimal" Nullable="false" />
          <Property Name="TotalDue" Type="Decimal" Nullable="false" />
          <Property Name="Comment" Type="String" />
          <Property Name="rowguid" Type="Guid" Nullable="false" />
          <Property Name="ModifiedDate" Type="DateTime" Nullable="false" />
          <NavigationProperty Name="Contact" 
Relationship="AdventureWorksModel.FK_SalesOrderHeader_Contact_ContactID"
            FromRole="SalesOrderHeader" ToRole="Contact" />
          <NavigationProperty Name="SalesOrderDetail"
Relationship="AdventureWorksModel.FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID"
            FromRole="SalesOrderHeader" ToRole="SalesOrderDetail" />
        </EntityType>

        <EntityType Name="AddressType">
          <Key>
            <PropertyRef Name="AddressTypeID" />
          </Key>
          <!-- Other properties -->
        </EntityType>

        <EntityType Name="Contact">
          <Key>
            <PropertyRef Name="ContactID" />
          </Key>
          <!-- Other properties -->
          <NavigationProperty Name="SalesOrderHeader"
Relationship="AdventureWorksModel.FK_SalesOrderHeader_Contact_ContactID" 
            FromRole="Contact" ToRole="SalesOrderHeader" />
        </EntityType>

        <EntityType Name="Product">
          <Key>
            <PropertyRef Name="ProductID" />
          </Key>
          <!-- Other properties -->
        </EntityType>


        <Association Name="FK_SalesOrderHeader_Contact_ContactID">
          <End Role="Contact" 
              Type="AdventureWorksModel.Contact" Multiplicity="1" />
          <End Role="SalesOrderHeader"
        Type="AdventureWorksModel.SalesOrderHeader" Multiplicity="*" />
        </Association>

        <Association Name="FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
          <End Role="SalesOrderHeader"
          Type="AdventureWorksModel.SalesOrderHeader" Multiplicity="1">
            <OnDelete Action="Cascade" />
          </End>
          <End Role="SalesOrderDetail"
           Type="AdventureWorksModel.SalesOrderDetail" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="SalesOrderHeader">
              <PropertyRef Name="SalesOrderID" />
            </Principal>
            <Dependent Role="SalesOrderDetail">
              <PropertyRef Name="SalesOrderID" />
            </Dependent>
          </ReferentialConstraint>
        </Association>
      </Schema>

Para obtener más información acerca de CSDL, vea Esquema conceptual (CSDL).

Procedimientos almacenados utilizados en el ejemplo

Para mostrar el uso de procedimientos almacenados, se proporcionan los scripts de base de datos siguientes para modificar la base de datos AdventureWorks. Los scripts crean procedimientos almacenados que crean, actualizan y eliminan instancias de SalesOrderDetail en el almacenamiento.

Nota

No se recomienda administrar las transacciones dentro de los procedimientos almacenados que usen datos de Entity Framework porque pueden estar en conflicto con el procesamiento de Entity Framework.

Procedimiento CreateSalesOrderDetail

El script siguiente crea el procedimiento almacenado que agrega elementos SalesOrderDetail al almacenamiento. El script contiene código que se puede utilizar para eliminar el procedimiento almacenado si no se necesita después de probar este ejemplo. Para eliminar el procedimiento almacenado, omita las líneas después de drop procedure y ejecute el script.

USE [AdventureWorks]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID ( 'dbo.CreateSalesOrderDetail', 'P' ) IS NOT NULL 
DROP PROCEDURE dbo.CreateSalesOrderDetail;
GO

CREATE PROCEDURE [dbo].[CreateSalesOrderDetail] 
   @SalesOrderID int,
   @CarrierTrackingNumber nvarchar(25),
   @OrderQty smallint,
   @ProductID int,
   @SpecialOfferID int,
   @UnitPrice money,
   @UnitPriceDiscount money,
   @rowguid uniqueidentifier,
   @ModifiedDate datetime
   
AS

INSERT INTO [AdventureWorks].[Sales].[SalesOrderDetail]
           ([SalesOrderID]
           ,[CarrierTrackingNumber]
           ,[OrderQty]
           ,[ProductID]
           ,[SpecialOfferID]
           ,[UnitPrice]
           ,[UnitPriceDiscount]
           ,[rowguid]
           ,[ModifiedDate])
     VALUES
           (@SalesOrderID,
           @CarrierTrackingNumber,
           @OrderQty,
           @ProductID,
           @SpecialOfferID,
           @UnitPrice,
           @UnitPriceDiscount,
           @rowguid,
           @ModifiedDate)

select SalesOrderDetailID, LineTotal
 from [AdventureWorks].[Sales].[SalesOrderDetail]
 where SalesOrderID = @SalesOrderID and SalesOrderDetailID = scope_identity()

Procedimiento UpdateSalesOrderDetail

El script siguiente crea el procedimiento almacenado que se usa para actualizar los elementos SalesOrderDetail en el almacenamiento.

USE [AdventureWorks]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID ( 'dbo.UpdateSalesOrderDetail', 'P' ) IS NOT NULL 
DROP PROCEDURE dbo.UpdateSalesOrderDetail;
GO

CREATE PROCEDURE [dbo].[UpdateSalesOrderDetail]
   @OrderQty smallint, 
   @SalesOrderDetailID int,
   @SalesOrderID int

AS
UPDATE [AdventureWorks].[Sales].[SalesOrderDetail]
   SET [OrderQty] = @OrderQty
 WHERE SalesOrderDetailID = @SalesOrderDetailID

Procedimiento DeleteSalesOrderDetail

El script siguiente crea el procedimiento almacenado que se usa para eliminar los elementos SalesOrderDetail en el almacenamiento.

USE [AdventureWorks]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID ( 'dbo.DeleteSalesOrderDetail', 'P' ) IS NOT NULL 
DROP PROCEDURE dbo.DeleteSalesOrderDetail;
GO

CREATE PROCEDURE [dbo].[DeleteSalesOrderDetail] 
   @SalesOrderDetailID int,
   @SalesOrderID int 
AS
DELETE FROM [AdventureWorks].[Sales].[SalesOrderDetail]
      WHERE SalesOrderDetailID = @SalesOrderDetailID

Lenguaje de definición de esquemas de almacenamiento (SSDL)

En el esquema de almacenamiento, los elementos Function definen los procedimientos almacenados disponibles en la base de datos. Los elementos Parameter anidados especifican los nombres de los parámetros de los procedimientos almacenados que pueden asignarse. Estas declaraciones informan al Entity Framework de que los procedimientos almacenados existen en la base de datos pero no especifican la asignación. La asignación se implementará como se muestra en el esquema de asignación posteriormente en este tema.

El atributo IsComposable de una declaración de función que representa un procedimiento almacenado debe estar establecido en false. Este valor indica que los resultados devueltos por el procedimiento no se pueden utilizar en la cláusula FROM de otras instrucciones de Entity SQL. Las declaraciones siguientes del esquema de almacenamiento especifican tres procedimientos almacenados: CreateSalesOrderDetail, UpdateSalesOrderDetail y DeleteSalesOrderDetail.

        <Function Name="CreateSalesOrderDetail" Aggregate="false"
                  BuiltIn="false" NiladicFunction="false"
                  IsComposable="false"
                  ParameterTypeSemantics="AllowImplicitConversion"
                  Schema="dbo">
          <Parameter Name="SalesOrderID" Type="int" Mode="In" />
          <Parameter Name="CarrierTrackingNumber" Type="nvarchar" Mode="In" />
          <Parameter Name="OrderQty" Type="smallint" Mode="In" />
          <Parameter Name="ProductID" Type="int" Mode="In" />
          <Parameter Name="SpecialOfferID" Type="int" Mode="In" />
          <Parameter Name="UnitPrice" Type="money" Mode="In" />
          <Parameter Name="UnitPriceDiscount" Type="money" Mode="In" />
          <Parameter Name="rowguid" Type="uniqueidentifier" Mode="In" />
          <Parameter Name="ModifiedDate" Type="datetime" Mode="In" />
        </Function>

        <Function Name="UpdateSalesOrderDetail" Aggregate="false"
                  BuiltIn="false" NiladicFunction="false"
                  IsComposable="false"
                  ParameterTypeSemantics="AllowImplicitConversion"
                  Schema="dbo">
          <Parameter Name="OrderQty" Type="smallint" Mode="In"/>
          <Parameter Name="SalesOrderDetailID" Type="int" Mode="In"/>
          <Parameter Name="SalesOrderID" Type="int" Mode="In"/>
        </Function>

        <Function Name="DeleteSalesOrderDetail" Aggregate="false"
                  BuiltIn="false" NiladicFunction="false"
                  IsComposable="false"
                  ParameterTypeSemantics="AllowImplicitConversion"
                  Schema="dbo">
          <Parameter Name="SalesOrderDetailID" Type="int" Mode="In"/>
          <Parameter Name="SalesOrderID" Type="int" Mode="In"/>
        </Function>

Para obtener el esquema de almacenamiento completo del modelo de ventas de AdventureWorks tal cual antes de agregar los procedimientos almacenados, vea Esquema de almacenamiento de AdventureWorks Sales (EDM).

Lenguaje de especificación de asignaciones (MSL)

La especificación de asignaciones define la asignación entre las funciones declaradas en el esquema de almacenamiento y los procedimientos almacenados de la base de datos.

Debajo del elemento EntityTypeMapping de un elemento EntitySetMapping, el elemento ModificationFunctionMapping describe qué funciones especificadas en el archivo de lenguaje de definición de esquemas de almacenamiento (SSDL) deberían administrar el procesamiento de los cambios. Los elementos secundarios incluyen DeleteFunction, InsertFunction y UpdateFunction. Cada asignación de función especifica el FunctionName del procedimiento almacenado que se asigna.

El elemento AssociationEnd dentro de EntityTypeMapping le permite tratar una relación como una referencia o clave externa, que es la base de una asociación que relaciona la entidad con otra entidad. Para obtener información sobre cómo crear o eliminar las asociaciones entre las entidades existentes por cada procedimiento almacenado, vea Asignar conjuntos de asociaciones a procedimientos almacenados (Entity Framework).

  <ModificationFunctionMapping >
    <InsertFunction
       FunctionName="AdventureWorksModel.Store.CreateSalesOrderDetail">
        <ScalarProperty Name="CarrierTrackingNumber"
              ParameterName="CarrierTrackingNumber" Version="Current"/>
        <ScalarProperty Name="OrderQty" ParameterName="OrderQty"
              Version="Current"/>
        <ScalarProperty Name="ProductID" ParameterName="ProductID" Version="Current"/>
         <ScalarProperty Name="SpecialOfferID"
              ParameterName="SpecialOfferID" Version="Current"/>
        <ScalarProperty Name="UnitPrice" 
              ParameterName="UnitPrice" Version="Current"/>
        <ScalarProperty Name="UnitPriceDiscount"
              ParameterName="UnitPriceDiscount" Version="Current"/>
        <ScalarProperty Name="rowguid" ParameterName="rowguid"
              Version="Current"/>
        <ScalarProperty Name="ModifiedDate"
              ParameterName="ModifiedDate" Version="Current"/>
        <AssociationEnd
           AssociationSet="FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID"
          From="SalesOrderDetail" To="SalesOrderHeader">
        <ScalarProperty Name="SalesOrderID"
                   ParameterName="SalesOrderID" />
        </AssociationEnd>
        <ResultBinding ColumnName="SalesOrderDetailID"
                   Name="SalesOrderDetailID" />
         <ResultBinding ColumnName="LineTotal" Name="LineTotal" />
  </InsertFunction>

    <UpdateFunction
    FunctionName="AdventureWorksModel.Store.UpdateSalesOrderDetail" >
        <ScalarProperty Name="OrderQty" ParameterName="OrderQty"
             Version="Current"/>
        <ScalarProperty Name="SalesOrderDetailID"
           ParameterName="SalesOrderDetailID" Version="Current"/>
        <AssociationEnd
    AssociationSet="FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID"
       From="SalesOrderDetail" To="SalesOrderHeader">
          <ScalarProperty Name="SalesOrderID"
            ParameterName="SalesOrderID" Version="Current" />
        </AssociationEnd>
    </UpdateFunction>

    <DeleteFunction
     FunctionName="AdventureWorksModel.Store.DeleteSalesOrderDetail" >
        <ScalarProperty Name="SalesOrderDetailID"
           ParameterName="SalesOrderDetailID" Version="Original"/>
        <AssociationEnd
           AssociationSet="FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID"
          From="SalesOrderDetail" To="SalesOrderHeader">
        <ScalarProperty Name="SalesOrderID"
                  ParameterName="SalesOrderID" />
        </AssociationEnd>
    </DeleteFunction>
  </ModificationFunctionMapping>

Para examinar el esquema de asignación correspondiente al modelo de AdventureWorks antes de agregar procedimientos almacenados, vea Esquema de asignación de AdventureWorks Sales (EDM).

Control de simultaneidad optimista

El atributo Version del elemento ScalarProperty admite el uso del control de simultaneidad optimista en las actualizaciones y eliminaciones. Puede especificar un atributo Version que tenga el valor original, como de lectura de la base de datos originalmente, o current, que puede haber sido cambiado por el código cliente. Es necesario especificar la versión en las asignaciones de la función de actualización. Es opcional en las asignaciones de la función de eliminación. En las inserciones, no se requiere ningún control de simultaneidad optimista porque no hay ningún valor original para probar con el origen de datos.

Establecer el atributo Version permite a los procedimientos almacenados tomar tanto los valores anteriores como los nuevos como parámetros al realizar el control de simultaneidad optimista. Ello le permite asegurarse de que una actualización o eliminación sólo se producirá si el origen de datos todavía contiene los mismos valores que la aplicación recuperada en último lugar del origen de datos.

Los parámetros de entrada enlazados a las versiones originales de las propiedades de entidad se utilizan en la cláusula WHERE de las instrucciones DELETE o UPDATE de un procedimiento almacenado. En las actualizaciones, los parámetros adicionales enlazados a las versiones actuales de propiedades de entidad se utilizan en la cláusula SET de una instrucción UPDATE en un procedimiento almacenado. De esta forma se comprueba que los valores nuevos y actuales solo se asignan al origen de datos cuando los valores originales todavía coinciden con los del origen de datos. Se producirá un error en la actualización o eliminación si otro usuario u otra aplicación han cambiado los valores en el origen de datos desde que se recuperaron los originales.

Recuperar los valores de servidor

En las inserciones y actualizaciones, un elemento secundario adicional, ResultBinding, permite devolver los valores generados por el servidor a través de un conjunto de resultados. El elemento ResultBinding especifica el modo en que los valores devueltos se corresponden con las propiedades de entidad y permiten a la canalización de la actualización establecer los valores de los objetos según el modelo conceptual.

El elemento ResultBinding tiene un atributo Name, que es el nombre de la propiedad en la definición de la entidad a la que se hace referencia, y un atributo ColumnName, que es el nombre de una columna del conjunto de resultados que el procedimiento almacenado devuelve. El elemento ResultBinding se muestra en el segmento del esquema siguiente.

    <ResultBinding Name="SalesOrderDetailID"
                    ColumnName="SalesOrderDetailID" />
    <ResultBinding Name="LineTotal" ColumnName="LineTotal" />
  </InsertFunction>

En el código del procedimiento almacenado, utilice una instrucción SELECT, después de ejecutarse la instrucción INSERT o UPDATE, para recuperar el valor que se pasa a ResultBinding.

SELECT SalesOrderDetailID, LineTotal
  FROM [AdventureWorks].[Sales].[SalesOrderDetail]
  WHERE SalesOrderID = @SalesOrderID and SalesOrderDetailID = scope_identity()

Vea también

Tareas

Cómo definir un modelo con un procedimiento almacenado (Entity Framework)

Conceptos

ModificationFunctionMapping (EntityTypeMapping)
ModificationFunctionMapping (AssociationSetMapping)
Recursos de Entity Framework
Terminología de Entity Framework
Asignar conjuntos de asociaciones a procedimientos almacenados (Entity Framework)

Otros recursos

Especificaciones del EDM
Especificación de asignaciones y esquemas (Entity Framework)
Tutorial: asignar una entidad a procedimientos almacenados