Prise en charge des procédures stockées (Entity Framework)

Le modèle EDM (Entity Data Model) prend en charge l'utilisation de procédures stockées pour l'extraction et la modification de données. Les procédures stockées peuvent être utilisées pour récupérer, insérer, mettre à jour et supprimer des données.

De nombreuses applications de base de données s'appuient sur les procédures stockées pour proposer les avantages suivants :

  • Sécurité. L'accès direct aux tables ou autres objets d'une base de données peut être refusé à certains de ses utilisateurs. Pour créer des points d'entrée uniques en vue de l'accès aux données, il suffit aux administrateurs de base de données d'accorder des autorisations d'exécution sur les procédures stockées. Cette façon de procéder réduit considérablement l'exposition aux attaques par injection de code SQL. Des paramètres d'entrée et de sortie configurés pour utiliser des valeurs par défaut permettent une validation stricte des paramètres. Le code de validation des procédures stockées peut limiter les actions possibles.

  • Encapsulation. Une logique de données complexe, des transactions explicites et d'autres opérations de base de données peuvent être écrites une fois dans le code d'une procédure stockée et exécutées depuis plusieurs applications clientes. Les erreurs, exceptions et violations de l'accès concurrentiel peuvent être contrôlées à partir d'un code côté serveur, ce qui réduit le nombre d'allers-retours entre différentes applications clientes. Le code d'une procédure stockée peut être modifié sans affecter les applications clientes, sous réserve que la signature de cette procédure stockée reste inchangée.

  • Prévisibilité. Les administrateurs de base de données sont souvent obligés de vérifier que les applications clientes ne publient pas de requêtes inefficaces susceptibles de réduire les performances du serveur. Les requêtes des procédures stockées peuvent être paramétrées individuellement afin de produire des plans d'exécution acceptables. Outre le paramétrage, des procédures stockées correctement écrites facilitent la résolution de problèmes, tels que des blocages, susceptibles de se présenter côté serveur.

  • Performances. Dans certaines situations, l'utilisation de procédures stockées peut se traduire par des gains de performances. Les moteurs de base de données modernes traitent généralement les instructions SQL dynamiques aussi efficacement que les instructions figurant dans des procédures stockées ; les administrateurs de base de données conservent un contrôle plus important sur les performances en instaurant l'utilisation de procédures stockées.

Dans le modèle objet EDM, les procédures stockées qui retournent des données sont appelées à partir de fonctions nommées. Les procédures stockées qui mettent à jour des données sont mappées à des entités et associations et sont appelées implicitement lorsque les opérations qu'elles définissent utiliseraient des méthodes générées par le système si les procédures stockées n'étaient pas été implémentées et mappées.

Cette rubrique décrit les procédures stockées utilisées pour mettre à jour des données par le biais de mappages spécifiés dans l'élément de schéma ModificationFunctionMapping. Les procédures stockées qui récupèrent des données utilisent l'élément FunctionImportMapping. Pour vous familiariser avec les procédures stockées qui récupèrent des données, mais ne le modifient pas, voir Procédure : définir un modèle avec une procédure stockée (Entity Framework).

Un autre scénario pouvant être géré par des procédures stockées est celui de l'insertion ou de la suppression d'une instance d'une association entre des entités existantes. Le mappage de procédures stockées à ces opérations est décrit dans Mappage d'ensembles d'associations à des procédures stockées (Entity Framework).

Par défaut, Entity Framework effectue directement des opérations sur des tables de base de données selon les mappages définis entre les schémas conceptuels et de stockage. La configuration d'Entity Framework pour l'utilisation de procédures stockées afin de mettre à jour des données exige par conséquent de modifier les schémas de stockage et de mappage.

Le tableau suivant contient des liens vers des rubriques qui expliquent l'utilisation de procédures stockées dans les différents scénarios pris en charge par le modèle EDM.

Opération Spécifications SSDL Spécifications MSL Spécifications CSDL

Exécuter une requête qui retourne des objets entité. Pour plus d'informations, voir Procédure : définir un modèle avec une procédure stockée (Entity Framework).

Ajouter un élément Function dans l'élément Schema du fichier de modèle de stockage. Cet élément référence une procédure stockée qui retourne un type d'entité.

Ajouter un élément FunctionImportMapping dans l'élément EntityContainerMapping du fichier de modèle conceptuel.

Ajouter un élément FunctionImport dans l'élément EntityContainer du fichier de modèle conceptuel.

Les procédures stockées sont utilisées pour insérer, mettre à jour et supprimer des données d'entité. Pour plus d'informations, voir Procédure : définir un modèle avec des procédures stockées de modification (Entity Framework).

Ajouter des éléments Function dans l'élément Schema du fichier de modèle de stockage. Effectuer cette opération une fois pour chaque procédure stockée d'insertion, de mise à jour et de suppression.

Ajouter un élément ModificationFunctionMapping dans l'élément EntityTypeMapping du type d'entité. Cet élément doit définir des éléments InsertFunction, UpdateFunction et DeleteFunction pour les procédures stockées d'insertion, de mise à jour et de suppression. Lorsque l'entité a des relations, un élément AssociationEnd spécifie l'association.

Aucune.

Les procédures stockées sont utilisées pour créer ou supprimer des relations plusieurs à plusieurs définies entre des types d'entités et implémentées dans la source de données à l'aide d'une table de lien. Pour plus d'informations, voir Mappage d'ensembles d'associations à des procédures stockées (Entity Framework).

Ajouter des éléments Function dans l'élément Schema du fichier de modèle de stockage. Effectuer cette opération une fois pour chaque procédure stockée qui crée ou supprime des relations dans la source de données.

Ajouter un élément ModificationFunctionMapping dans l'Élément AssociationSetMapping de l'association. Cet élément doit définir les éléments InsertFunction et DeleteFunction pour les procédures stockées qui créent et suppriment des relations pour cette association.

Aucune.

Modifications de données et procédures stockées

Les procédures stockées utilisées pour la modification de données remplacent les méthodes générées par Entity Framework. Les procédures stockées sont appelées de façon implicite, de sorte qu'aucune modification du modèle EDM défini dans le schéma conceptuel ou un code d'application existant n'est requise.

CSDL

Le segment CSDL (Conceptual Schema Definition Language) suivant définit une entité SalesOrderHeader et une entité SalesOrderDetail. Les deux types sont basés sur l'exemple de base de données AdventureWorks fourni avec SQL Server 2005 et SQL Server 2008. Aucune modification CSDL du schéma CSDL n'est requise pour utiliser des procédures stockées en vue de modifier les données du modèle EDM, mais le schéma CSDL est inclus ici à des fins de précision. Ce schéma omet certaines définitions de propriétés pour des raisons de concision. Le schéma complet est disponible dans l'exemple du modèle de vente Modèle de vente AdventureWorks Sales Model (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>

Pour plus d'informations sur le langage CSDL, voir Schéma conceptuel (CSDL).

Procédures stockées utilisées dans l'exemple

Les scripts de base de données suivants, qui permettent de modifier la base de données AdventureWorks, sont fournis ici pour illustrer l'utilisation des procédures stockées. Ces scripts créent des procédures stockées qui créent, mettent à jour et suppriment des instances de SalesOrderDetail dans le stockage.

NoteRemarque

La gestion de transactions dans des procédures stockées utilisées par Entity Framework n'est pas recommandée, car elle peut présenter des conflits avec le traitement Entity Framework.

Procédure CreateSalesOrderDetail

Le script suivant crée la procédure stockée qui ajoute des éléments SalesOrderDetail au stockage. Le script contient du code qui peut être utilisé pour supprimer la procédure stockée si celle-ci n'est plus utile une fois l'exemple testé. Pour supprimer la procédure stockée, omettez les lignes situées après drop procedure et exécutez le 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()

Procédure UpdateSalesOrderDetail

Le script suivant crée la procédure stockée utilisée pour mettre à jour des éléments SalesOrderDetail dans le stockage.

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

Procédure DeleteSalesOrderDetail

Le script suivant crée la procédure stockée utilisée pour supprimer des éléments SalesOrderDetail dans le stockage.

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

SSDL (Store Schema Definition Language)

Dans le schéma de stockage, les éléments Function définissent les procédures stockées disponibles dans la base de données. Les éléments Parameter imbriqués spécifient les noms des paramètres des procédures stockées qui peuvent être mappées. Ces déclarations informent Entity Framework que les procédures stockées existent dans la base de données, mais ne spécifient pas de mappage. Le mappage sera implémenté dans le schéma de mappage comme indiqué plus loin dans cette rubrique.

L'attribut IsComposable d'une déclaration de fonction qui représente une procédure stockée doit avoir la valeur false. Ce paramètre indique que les résultats retournés par la procédure ne peuvent pas être utilisés dans la clause FROM d'autres instructions Entity SQL. Les déclarations suivantes dans le schéma de stockage spécifient trois procédures stockées : CreateSalesOrderDetail, UpdateSalesOrderDetail et 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>

Pour obtenir le schéma de stockage complet du modèle de vente AdventureWorks Sales Model tel qu'avant l'ajout des procédures stockées, voir Schéma de stockage de l'exemple de base de données AdventureWorks Sales (EDM).

MSL (Mapping Specification Language)

La spécification du mappage définit le mappage entre les fonctions déclarées dans le schéma de stockage et les procédures stockées de la base de données.

Sous l'élément EntityTypeMapping d'un EntitySetMapping, l'élément ModificationFunctionMapping décrit quelles fonctions spécifiées dans le fichier SSDL (Store Schema Definition Language) doivent gérer le traitement des modifications. Les éléments enfants incluent DeleteFunction, InsertFunction et UpdateFunction. Chaque mappage de fonction spécifie le FunctionName de la procédure stockée qui est mappée.

L'élément AssociationEnd d'EntityTypeMapping vous permet de traiter une relation comme une référence, ou clé étrangère, qui constitue la base d'une association qui met en relation deux entités. Pour plus d'informations sur la création ou la suppression par le bais de procédures stockées d'associations définies entre des entités existantes, voir Mappage d'ensembles d'associations à des procédures stockées (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>

Pour examiner le schéma de mappage du modèle AdventureWorks avant ajout de procédures stockées, voir Schéma de mappage des ventes AdventureWorks (EDM).

Contrôle d'accès concurrentiel optimiste

L'attribut Version de l'élément ScalarProperty prend en charge l'utilisation du contrôle d'accès concurrentiel optimiste pour les mises à jour et les suppressions. Vous pouvez spécifier un attribut Version ayant pour valeur original, pour indiquer qu'il s'agit de la version d'origine lue de la base de données, ou current, pour indiquer une version éventuellement modifiée par un code client. La spécification de la version est requise dans les mappages de fonctions de mise à jour. La spécification de la version est facultative pour les mappages de fonctions de suppression. Pour les insertions, aucun contrôle d'accès concurrentiel optimiste n'est requis, car aucune valeur d'origine ne doit être comparée à la source de données.

La définition de l'attribut Version permet aux procédures stockées d'accepter des valeurs anciennes et nouvelles en tant que paramètres lors du contrôle d'accès concurrentiel optimiste. Vous êtes ainsi certain qu'une mise à jour ou une suppression n'interviendra que si la source de données contient toujours les valeurs que l'application y a récupérées la dernière fois.

Les paramètres d'entrée liés aux versions d'origine de propriétés d'entité sont utilisés dans la clause WHERE d'une instruction UPDATE ou DELETE d'une procédure stockée. Pour les mises à jour, des paramètres supplémentaires, liés aux versions actuelles de propriétés d'entité, sont utilisés dans la clause SET d'une instruction UPDATE d'une procédure stockée. De cette façon, les valeurs nouvelles ou actuelles ne sont assignées à la source de données que lorsque les valeurs d'origine correspondent toujours à celles de la source de données. La mise à jour ou la suppression échoue si un autre utilisateur ou une autre application a modifié les valeurs de la source de données depuis la récupération des valeurs d'origine.

Récupération de valeurs du serveur

Pour les insertions et les mises à jour, un élément enfant supplémentaire, ResultBinding, prend en charge le retour de valeurs générées par le serveur via un jeu de résultats. L'élément ResultBinding spécifie comment les valeurs de retour correspondent à des propriétés d'entité et permettent au pipeline de mise à jour de définir des valeurs dans des objets basés sur le modèle conceptuel.

L'élément ResultBinding a un attribut Name, qui est le nom de la propriété dans la définition d'entité référencée, et un attribut ColumnName, qui est le nom d'une colonne dans le jeu de résultats retourné par la procédure stockée. L'élément ResultBinding est représenté dans le segment de schéma suivant.

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

Dans le code de la procédure stockée, utilisez une instruction SELECT, une fois l'instruction INSERT ou UPDATE exécutée, afin de récupérer la valeur passée à ResultBinding.

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

Voir aussi

Tâches

Procédure : définir un modèle avec une procédure stockée (Entity Framework)

Concepts

ModificationFunctionMapping (EntityTypeMapping)
ModificationFunctionMapping (AssociationSetMapping)
Ressources Entity Framework
Terminologie Entity Framework
Mappage d'ensembles d'associations à des procédures stockées (Entity Framework)

Autres ressources

Spécifications EDM
Schémas et spécification de mappage (Entity Framework)
Procédure pas à pas : mappage d'une entité à des procédures stockées