Condividi tramite


Supporto delle stored procedure (Entity Framework)

Il modello EDM (Entity Data Model) supporta l'utilizzo delle stored procedure per il recupero e la modifica dei dati. Le stored procedure possono essere utilizzate per recuperare, inserire, aggiornare ed eliminare i dati.

Molte applicazioni di database si basano sulle stored procedure per offrire i vantaggi seguenti:

  • Sicurezza: agli utenti del database è possibile negare l'accesso diretto a tabelle o altri oggetti di database. Per creare singoli punti di ingresso per l'accesso ai dati, è necessario che gli amministratori del database concedano solo le autorizzazioni di esecuzione sulle stored procedure. Così facendo si riduce in modo significativo l'area vulnerabile agli attacchi SQL. I parametri di input e di output configurati per l'uso dei valori predefiniti consentono la convalida di tipo strict dei parametri. Il codice di convalida nelle stored procedure può limitare le azioni disponibili.

  • Incapsulamento: la logica dei dati complessi, le transazioni esplicite e altre operazioni del database possono essere scritte una volta nel codice delle stored procedure ed eseguite da più applicazioni client. Gli errori, le eccezioni e le violazioni di concorrenza possono essere gestiti dal codice sul lato server, riducendo il numero di round trip dalle applicazioni client. Il codice delle stored procedure può essere modificato senza influire sulle applicazioni client purché la firma delle stored procedure rimanga immutata.

  • Prevedibilità: gli amministratori del database devono verificare di frequente che le applicazioni client non eseguano query inefficienti che possono influire in modo negativo sulle prestazioni del server. Le query nelle stored procedure possono essere ottimizzate singolarmente per produrre piani di esecuzione accettabili. Oltre all'ottimizzazione, le stored procedure scritte in modo corretto semplificano la risoluzione di problemi sul lato server quali blocchi e deadlock.

  • Prestazioni: in alcune situazioni l'uso delle stored procedure può risultare vantaggioso in termini di prestazioni. I moderni motori di database in genere gestiscono le istruzioni SQL dinamiche in modo analogo alle istruzioni contenute nelle stored procedure. Gli amministratori del database dispongono di un maggiore controllo sulle prestazioni grazie all'uso delle stored procedure.

Le stored procedure che restituiscono dati vengono chiamate dalle funzioni denominate nel modello a oggetti EDM. Le stored procedure che aggiornano i dati vengono mappate a entità e associazioni e vengono chiamate in modo implicito quando le operazioni che definiscono utilizzerebbero metodi generati dal sistema se le stored procedure non fossero implementate e mappate.

In questo argomento vengono descritte le stored procedure utilizzate per aggiornare i dati mediante mapping specificati nell'elemento dello schema ModificationFunctionMapping. Le stored procedure che recuperano dati utilizzano l'elemento FunctionImportMapping. Per una guida introduttiva alle stored procedure che recuperano dati senza modificarli, vedere Procedura: definire un modello con una stored procedure (Entity Framework).

Un altro scenario che può essere gestito dalle stored procedure è l'inserimento o l'eliminazione di un'istanza di un'associazione tra entità esistenti. Nella sezione Mapping di set di associazioni alle stored procedure (Entity Framework) viene descritto il mapping delle stored procedure a queste operazioni.

Per impostazione predefinita, Entity Framework esegue le operazioni direttamente sulle tabelle di database in base ai mapping tra gli schemi concettuale e di archiviazione. Per configurare Entity Framework in modo da utilizzare le stored procedure per aggiornare i dati è necessario modificare gli schemi di archiviazione e di mapping.

Nella tabella seguente sono contenuti collegamenti ad argomenti nei quali viene illustrato l'uso delle stored procedure in diversi scenari supportati dal modello EDM.

Operazione Requisiti SSDL Requisiti MSL Requisiti CSDL

Eseguire una query che restituisca oggetti entità. Per ulteriori informazioni, vedere Procedura: definire un modello con una stored procedure (Entity Framework).

Aggiungere un elemento Function all'interno dell'elemento Schema del file del modello di archiviazione. Tale elemento fa riferimento a una stored procedure che restituisce un tipo di entità.

Aggiungere un elemento FunctionImportMapping nell'elemento EntityContainerMapping del file del modello concettuale.

Aggiungere un elemento FunctionImport nell'elemento EntityContainer del file del modello concettuale.

Le stored procedure vengono utilizzate per inserire, aggiornare ed eliminare i dati di entità. Per ulteriori informazioni, vedere Procedura: definire un modello mediante stored procedure di modifica (Entity Framework).

Aggiungere elementi Function all'interno dell'elemento Schema del file del modello di archiviazione. Effettuare questa operazione una volta per ogni stored procedure di inserimento, aggiornamento ed eliminazione.

Aggiungere un elemento ModificationFunctionMapping nell'elemento EntityTypeMapping del tipo di entità. Questo elemento deve definire gli elementi InsertFunction, UpdateFunction e DeleteFunction per le stored procedure di inserimento, aggiornamento ed eliminazione. Quando l'entità presenta relazioni, un elemento AssociationEnd specifica l'associazione.

Nessuno.

Le stored procedure vengono utilizzate per creare o eliminare relazioni molti-a-molti tra tipi di entità, che vengono implementate nell'origine dati utilizzando una tabella dei collegamenti. Per ulteriori informazioni, vedere Mapping di set di associazioni alle stored procedure (Entity Framework).

Aggiungere elementi Function all'interno dell'elemento Schema del file del modello di archiviazione. Eseguire questa operazione una volta per ogni stored procedure che crea o elimina relazioni nell'origine dati.

Aggiungere un elemento ModificationFunctionMapping nell'elemento AssociationSetMapping dell'associazione. Tale elemento deve definire gli elementi InsertFunction e DeleteFunction per le stored procedure che creano ed eliminano relazioni per l'associazione.

Nessuno.

Modifiche dei dati e stored procedure

Le stored procedure utilizzate per la modifica dei dati sostituiscono i metodi generati da Entity Framework. Poiché le stored procedure vengono chiamate in modo implicito, non è necessario apportare modifiche al modello EDM definito nello schema concettuale o nel codice dell'applicazione esistente.

CSDL

Il segmento CSDL (Conceptual Schema Definition Language) seguente definisce un'entità SalesOrderHeader e un'entità SalesOrderDetail. Entrambi i tipi si basano sul database di esempio AdventureWorks fornito con SQL Server 2005 e SQL Server 2008. Per utilizzare le stored procedure allo scopo di modificare i dati EDM non è necessario apportare modifiche CSDL allo schema CSDL. Tale schema è illustrato di seguito per maggiore completezza. Nello schema sono omesse alcune definizioni di proprietà per brevità. Lo schema completo è disponibile nell'esempio in Modello Sales di AdventureWorks (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>

Per ulteriori informazioni su CSDL, vedere Schema concettuale (CSDL).

Stored procedure utilizzate nell'esempio

Per illustrare l'utilizzo delle stored procedure, di seguito sono riportati script di database che consentono di modificare il database AdventureWorks. Gli script creano stored procedure che creano, aggiornano ed eliminano istanze di SalesOrderDetail nell'archivio.

NoteNota

La gestione delle transazioni nelle stored procedure utilizzate dai dati Entity Framework non è consigliata perché potrebbe generare conflitti con le operazioni di elaborazione di Entity Framework.

Procedura CreateSalesOrderDetail

Nello script seguente viene creata la stored procedure che aggiunge elementi SalesOrderDetail nell'archivio. Lo script contiene codice che può essere utilizzato per eliminare la stored procedure se non è necessaria al termine del testing dell'esempio. Per eliminare la stored procedure, omettere le righe dopo drop procedure ed eseguire lo 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()

Procedura UpdateSalesOrderDetail

Nello script seguente viene creata la stored procedure utilizzata per aggiornare elementi SalesOrderDetail nell'archivio.

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

Procedura DeleteSalesOrderDetail

Nello script seguente viene creata la stored procedure utilizzata per eliminare elementi SalesOrderDetail nell'archivio.

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)

Nello schema di archiviazione gli elementi Function definiscono le stored procedure disponibili nel database. Gli elementi Parameter nidificati specificano i nomi dei parametri delle stored procedure che possono essere mappati. Queste dichiarazioni informano Entity Framework che le stored procedure esistono nel database ma non specificano mapping. Come illustrato più avanti in questo argomento, il mapping verrà implementato nello schema di mapping.

L'attributo IsComposable di una dichiarazione di funzione che rappresenta una stored procedure deve essere impostato su false. Questa impostazione indica che i risultati restituiti dalla procedura non possono essere utilizzati nella clausola FROM di altre istruzioni Entity SQL. Le dichiarazioni seguenti nello schema di archiviazione specificano tre stored procedure, ovvero CreateSalesOrderDetail, UpdateSalesOrderDetail e 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>

Per lo schema di archiviazione completo del modello Sales di AdventureWorks così come si presenta prima dell'aggiunta delle stored procedure, vedere Schema di archiviazione del modello Sales di AdventureWorks (EDM).

MSL (Mapping Specification Language)

La specifica del mapping definisce il mapping tra funzioni dichiarate nello schema di archiviazione e stored procedure nel database.

Nell'elemento EntityTypeMapping di un EntitySetMapping, l'elemento ModificationFunctionMapping descrive le funzioni specificate nell'elaborazione delle modifiche di gestione dei file SSDL. Gli elementi figlio includono DeleteFunction, InsertFunctione UpdateFunction. Il mapping di ogni funzione specifica l'oggetto FunctionName per la stored procedure mappata.

L'elemento AssociationEnd all'interno di EntityTypeMapping consente di considerare una relazione come riferimento, o chiave esterna, ovvero la base di un'associazione che correla l'entità a un'altra entità. Per informazioni sulla creazione o l'eliminazione delle associazioni tra entità esistenti mediante le stored procedure, vedere Mapping di set di associazioni alle stored procedure (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>

Per esaminare lo schema di mapping per il modello AdventureWorks prima di aggiungere stored procedure, vedere Schema di mapping del modello Sales di AdventureWorks (EDM).

Controllo della concorrenza ottimistica

L'attributo Version dell'elemento ScalarProperty supporta l'uso del controllo della concorrenza ottimistica per gli aggiornamenti e le eliminazioni. È possibile specificare un attributo Version con il valore original per indicare la lettura originale dal database o con il valore current per indicare modifiche potenziali apportate dal codice client. La specifica della versione è necessaria nei mapping della funzione di aggiornamento. La specifica della versione è facoltativa per i mapping della funzione di eliminazione. Per gli inserimenti, non è richiesto alcun controllo della concorrenza ottimistica perché non vi sono valori originali da testare rispetto all'origine dati.

Grazie all'impostazione dell'attributo Version, le stored procedure possono accettare sia valori vecchi che valori nuovi come parametri durante l'esecuzione del controllo della concorrenza ottimistica. In questo modo l'utente può assicurarsi che un aggiornamento o un'eliminazione venga eseguito solo se l'origine dati contiene ancora valori identici agli ultimi valori che l'applicazione ha recuperato dall'origine dati.

I parametri di input associati alle versioni originali delle proprietà dell'entità vengono utilizzati nella clausola WHERE di un'istruzione UPDATE o DELETE in una stored procedure. Per gli aggiornamenti, vengono utilizzati altri parametri associati alle versioni correnti delle proprietà dell'entità nella clausola SET di un'istruzione UPDATE in una stored procedure. In questo modo si garantisce che i valori nuovi e correnti vengano assegnati all'origine dati solo quando i valori originali corrispondono ancora ai valori presenti nell'origine dati. L'aggiornamento o l'eliminazione non riuscirà se un altro utente o un'altra applicazione ha modificato i valori nell'origine dati in seguito al recupero dei valori originali.

Recupero dei valori del server

Per gli inserimenti e gli aggiornamenti, un altro elemento figlio, ResultBinding, supporta la restituzione dei valori generati dal server mediante un set di risultati. L'elemento ResultBinding specifica in che modo i valori restituiti corrispondono alle proprietà dell'entità e consente alla pipeline di aggiornamento di impostare valori negli oggetti in base al modello concettuale.

L'elemento ResultBinding include un attributo Name che indica il nome della proprietà nella definizione dell'entità di riferimento e un attributo ColumnName che indica il nome di una colonna nel set di risultati restituito dalla stored procedure. L'elemento ResultBinding è illustrato nel segmento di schema seguente.

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

Nel codice della stored procedure utilizzare un'istruzione SELECT, dopo l'esecuzione dell'istruzione INSERT o UPDATE, per recuperare il valore passato a ResultBinding.

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

Vedere anche

Attività

Procedura: definire un modello con una stored procedure (Entity Framework)

Concetti

ModificationFunctionMapping (EntityTypeMapping)
ModificationFunctionMapping (AssociationSetMapping)
Risorse di Entity Framework
Terminologia relativa a Entity Framework
Mapping di set di associazioni alle stored procedure (Entity Framework)

Altre risorse

Specifiche EDM
Specifica di schemi e mapping (Entity Framework)
Procedura dettagliata: mapping di un'entità alle stored procedure