다음을 통해 공유


저장 프로시저 지원(Entity Framework)

EDM(엔터티 데이터 모델)은 저장 프로시저를 사용한 데이터 검색 및 수정을 지원합니다. 저장 프로시저를 사용하여 데이터를 검색, 삽입, 업데이트 및 삭제할 수 있습니다.

많은 데이터베이스 응용 프로그램은 저장 프로시저를 사용하여 다음과 같은 이점을 제공합니다.

  • 보안. 테이블 또는 다른 데이터베이스 개체에 대한 데이터베이스 사용자의 직접 액세스가 거부될 수 있습니다. 데이터베이스 관리자가 데이터 액세스를 위한 단일 진입점을 만들려는 경우 저장 프로시저에 대한 실행 권한만 부여하면 됩니다. 그러면 SQL 삽입 공격에 노출되는 영역이 훨씬 줄어듭니다. 기본값을 사용하도록 구성된 입력 및 출력 매개 변수는 엄격한 매개 변수 유효성 검사를 가능하게 합니다. 저장 프로시저의 유효성 검사 코드로 사용 가능한 작업을 제한할 수 있습니다.

  • 캡슐화. 복잡한 데이터 논리, 명시적 트랜잭션 및 기타 데이터베이스 작업을 저장 프로시저 코드로 한 번 작성한 다음 여러 클라이언트 응용 프로그램에서 실행할 수 있습니다. 서버 쪽 코드에서 오류, 예외 및 동시성 위반을 처리하여 클라이언트 응용 프로그램에서의 왕복 수를 줄일 수 있습니다. 저장 프로시저의 서명이 변경되지 않는 한 클라이언트 응용 프로그램에 영향을 주지 않고 저장 프로시저 코드를 수정할 수 있습니다.

  • 예측 가능성. 데이터베이스 관리자는 클라이언트 응용 프로그램에서 서버 성능을 저하시킬 수 있는 비효율적인 쿼리를 실행하지 않는지 자주 확인해야 합니다. 저장 프로시저의 쿼리를 개별적으로 조정하여 적절한 실행 계획을 만들 수 있습니다. 제대로 작성된 저장 프로시저는 조정뿐 아니라 차단 및 교착 상태와 같은 서버 쪽 문제도 간단하게 해결합니다.

  • 성능. 경우에 따라 저장 프로시저를 사용할 때 성능이 향상될 수 있습니다. 현대적인 데이터베이스 엔진은 일반적으로 동적 SQL 문을 저장 프로시저의 문처럼 효율적으로 처리합니다. 데이터베이스 관리자는 저장 프로시저 사용을 강제하여 성능을 보다 강력하게 제어할 수 있습니다.

데이터를 반환하는 저장 프로시저는 EDM 개체 모델의 명명된 함수에서 호출됩니다. 데이터를 업데이트하는 저장 프로시저는 엔터티와 연결에 매핑되고, 저장 프로시저가 구현 및 매핑되지 않은 경우 정의하는 작업에서 시스템 생성 메서드를 사용할 때 암시적으로 호출됩니다.

이 항목에서는 ModificationFunctionMapping 스키마 요소에 지정된 매핑을 통해 데이터를 업데이트하는 데 사용되는 저장 프로시저에 대해 설명합니다. 데이터를 검색하는 저장 프로시저는 FunctionImportMapping 요소를 사용합니다. 데이터를 검색하지만 변경하지 않는 저장 프로시저에 대한 퀵 스타트는 방법: 저장 프로시저로 모델 정의(Entity Framework)를 참조하십시오.

저장 프로시저에서 관리할 수 있는 다른 시나리오는 기존 엔터티 간 연결 인스턴스의 삽입 또는 삭제입니다. 저장 프로시저를 이러한 작업에 매핑하는 방법은 연결 집합을 저장 프로시저에 매핑(Entity Framework)에 설명되어 있습니다.

기본적으로 Entity Framework는 개념 스키마와 저장소 스키마 간의 매핑을 기반으로 데이터베이스 테이블에 대해 직접 작업을 수행합니다. 저장 프로시저를 사용하여 데이터를 업데이트하도록 Entity Framework를 구성하려면 저장소 및 매핑 스키마를 수정해야 합니다.

다음 표에는 EDM이 지원하는 여러 시나리오에서 저장 프로시저의 사용을 설명하는 항목에 대한 링크가 들어 있습니다.

작업 SSDL 요구 사항 MSL 요구 사항 CSDL 요구 사항

엔터티 개체를 반환하는 쿼리를 실행합니다. 자세한 내용은 방법: 저장 프로시저로 모델 정의(Entity Framework)를 참조하십시오.

저장소 모델 파일의 Schema 요소 내부에 Function 요소를 추가합니다. 이 요소는 엔터티 형식을 반환하는 저장 프로시저를 참조합니다.

개념적 모델 파일의 EntityContainerMapping 요소에 FunctionImportMapping 요소를 추가합니다.

개념적 모델 파일의 EntityContainer 요소에 FunctionImport 요소를 추가합니다.

저장 프로시저는 엔터티 데이터를 삽입, 업데이트 및 삭제하는 데 사용됩니다. 자세한 내용은 방법: 수정 저장 프로시저로 모델 정의(Entity Framework)를 참조하십시오.

저장소 모델 파일의 Schema 요소 내부에 Function 요소를 추가합니다. 각 삽입, 업데이트 및 삭제 저장 프로시저에 대해 이 작업을 한 번 수행합니다.

엔터티 형식에 대한 EntityTypeMapping 요소에 ModificationFunctionMapping 요소를 추가합니다. 이 요소는 삽입, 업데이트 및 삭제 저장 프로시저에 대한 InsertFunction, UpdateFunctionDeleteFunction 요소를 정의해야 합니다. 엔터티에 관계가 있는 경우 AssociationEnd 요소에서 연결을 지정합니다.

없음

저장 프로시저는 링크 테이블을 사용하여 데이터 소스에서 구현된 엔터티 형식 간의 다 대 다 관계를 만들거나 삭제하는 데 사용됩니다. 자세한 내용은 연결 집합을 저장 프로시저에 매핑(Entity Framework)을 참조하십시오.

저장소 모델 파일의 Schema 요소 내부에 Function 요소를 추가합니다. 데이터 소스에 관계를 만들거나 삭제하는 각 저장 프로시저에 대해 이 작업을 한 번 수행합니다.

연결에 대한 AssociationSetMapping 요소에 ModificationFunctionMapping 요소를 추가합니다. 이 요소는 이 연결의 관계를 만들고 삭제하는 저장 프로시저에 대한 InsertFunctionDeleteFunction 요소를 정의해야 합니다.

없음

데이터 수정 및 저장 프로시저

데이터 수정에 사용되는 저장 프로시저는 Entity Framework에서 생성된 메서드를 대체합니다. 저장 프로시저는 암시적으로 호출되므로 개념 스키마 또는 기존 응용 프로그램 코드에서 정의된 EDM을 변경할 필요가 없습니다.

CSDL

다음 CSDL(개념 스키마 정의 언어) 세그먼트는 SalesOrderHeader 엔터티와 SalesOrderDetail 엔터티를 정의합니다. 두 형식은 모두 SQL Server 2005 및 SQL Server 2008과 함께 제공되는 AdventureWorks 샘플 데이터베이스를 기반으로 합니다. 저장 프로시저를 사용하여 EDM 데이터를 수정하기 위해 CSDL 스키마에서 CSDL을 수정할 필요는 없지만 여기서는 완결성을 위해 CSDL 스키마를 표시합니다. 이 스키마는 간결성을 위해 일부 속성 정의를 생략합니다. 전체 스키마는 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>

CSDL에 대한 자세한 내용은 개념 스키마(CSDL)를 참조하십시오.

예제에서 사용된 저장 프로시저

저장 프로시저 사용을 보여 주기 위해 AdventureWorks 데이터베이스를 수정하는 다음 데이터베이스 스크립트가 제공됩니다. 이 스크립트는 저장소에 SalesOrderDetail 인스턴스를 만들고, 업데이트 및 삭제하는 저장 프로시저를 만듭니다.

Note참고

Entity Framework 데이터에서 사용하는 저장 프로시저 내의 트랜잭션 관리는 Entity Framework 처리와 충돌할 수 있으므로 사용하지 않는 것이 좋습니다.

CreateSalesOrderDetail 프로시저

다음 스크립트는 SalesOrderDetail 항목을 저장소에 추가하는 저장 프로시저를 만듭니다. 이 스크립트에는 이 예제를 테스트한 후 필요하지 않을 경우 저장 프로시저를 삭제하는 데 사용할 수 있는 코드가 들어 있습니다. 저장 프로시저를 삭제하려면 drop procedure 뒤에 있는 줄을 생략하고 스크립트를 실행합니다.

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()

UpdateSalesOrderDetail 프로시저

다음 스크립트는 저장소의 SalesOrderDetail 항목을 업데이트하는 데 사용되는 저장 프로시저를 만듭니다.

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

DeleteSalesOrderDetail 프로시저

다음 스크립트는 저장소의 SalesOrderDetail 항목을 삭제하는 데 사용되는 저장 프로시저를 만듭니다.

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(저장소 스키마 정의 언어)

저장소 스키마에서 Function 요소는 데이터베이스에서 사용할 수 있는 저장 프로시저를 정의합니다. 중첩된 Parameter 요소는 매핑할 수 있는 저장 프로시저의 매개 변수 이름을 지정합니다. 이러한 선언은 저장 프로시저가 데이터베이스에 있지만 매핑을 지정하지 않음을 Entity Framework에 알립니다. 매핑은 이 항목의 뒷부분에 표시된 대로 매핑 스키마에서 구현됩니다.

저장 프로시저를 나타내는 함수 선언의 IsComposable 특성은 false로 설정되어야 합니다. 이것은 프로시저에서 반환된 결과가 다른 Entity SQL 문의 FROM 절에 사용될 수 없다는 것을 나타냅니다. 저장소 스키마의 다음 선언은 CreateSalesOrderDetail, UpdateSalesOrderDetailDeleteSalesOrderDetail이라는 세 개의 저장 프로시저를 지정합니다.

        <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>

저장 프로시저를 추가하기 전에 AdventureWorks Sales 모델의 전체 저장소 스키마가 존재할 경우 해당 스키마에 대한 내용은 AdventureWorks Sales 저장소 스키마(EDM)를 참조하십시오.

MSL(매핑 사양 언어)

매핑 사양은 저장소 스키마에서 선언된 함수와 데이터베이스의 저장 프로시저 간 매핑을 정의합니다.

EntitySetMappingEntityTypeMapping 요소 아래에서 ModificationFunctionMapping 요소는 SSDL 파일에 지정된 함수 중 변경 처리를 수행할 함수에 대해 설명합니다. 자식 요소에는 DeleteFunction, InsertFunctionUpdateFunction이 포함됩니다. 각 함수 매핑은 매핑되는 저장 프로시저에 대한 FunctionName을 지정합니다.

EntityTypeMapping 내의 AssociationEnd 요소를 사용하여 관계를 엔터티와 다른 엔터티 간의 관계를 지정하는 연결의 기반이 되는 참조 또는 외래 키로 처리할 수 있습니다. 저장 프로시저로 기존 엔터티 간의 연결을 만들거나 삭제하는 방법은 연결 집합을 저장 프로시저에 매핑(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>

저장 프로시저를 추가하기 전에 AdventureWorks 모델의 매핑 스키마를 검사하려면 AdventureWorks Sales 매핑 스키마(EDM)을 참조하십시오.

낙관적 동시성 제어

ScalarProperty 요소의 Version 특성은 업데이트 및 삭제에 대한 낙관적 동시성 제어 사용을 지원합니다. 처음 데이터베이스에서 읽은 original 값이나 클라이언트 코드에서 잠재적으로 변경될 수 있는 current 값을 가진 Version 특성을 지정할 수 있습니다. 업데이트 함수 매핑에서는 버전 지정이 필수 사항이지만 삭제 함수 매핑에서는 버전 지정이 선택 사항입니다. 삽입의 경우 데이터 소스에 대해 테스트할 원래 값이 없으므로 낙관적 동시성 제어가 필요하지 않습니다.

Version 특성을 설정하면 저장 프로시저가 낙관적 동시성 제어를 수행할 때 이전 값과 새 값을 모두 매개 변수로 사용할 수 있습니다. 이 특성을 사용하여 응용 프로그램이 데이터 소스에서 마지막으로 검색한 값과 동일한 값이 데이터 소스에 있는 경우에만 업데이트 또는 삭제가 수행되도록 할 수 있습니다.

엔터티 속성의 원래 버전에 바인딩된 입력 매개 변수는 저장 프로시저에 있는 UPDATE 또는 DELETE 문의 WHERE 절에 사용됩니다. 업데이트의 경우 엔터티 속성의 현재 버전에 바인딩된 추가 매개 변수가 저장 프로시저에 있는 UPDATE 문의 SET 절에 사용됩니다. 이 매개 변수는 원래 값이 데이터 소스의 값과 일치하는 경우에만 새로운 현재 값이 데이터 소스에 할당되는지 확인합니다. 원래 값이 검색된 이후 다른 사용자 또는 다른 응용 프로그램이 데이터 소스의 값을 변경한 경우 업데이트 또는 삭제가 실패합니다.

서버 값 검색

삽입 및 업데이트의 경우 추가 자식 요소인 ResultBinding에서 결과 집합을 통한 서버 생성 값 반환을 지원합니다. ResultBinding 요소는 반환 값이 엔터티 속성과 일치되는 방법을 지정하고 업데이트 파이프라인에서 개념적 모델을 기반으로 개체의 값을 설정할 수 있게 합니다.

ResultBinding 요소에는 참조된 엔터티 정의의 속성 이름인 Name 특성과 저장 프로시저에서 반환된 결과 집합의 열 이름인 ColumnName 특성이 있습니다. ResultBinding 요소는 다음 스키마 세그먼트에 나와 있습니다.

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

저장 프로시저 코드에서 INSERT 또는 UPDATE 문이 실행된 후 SELECT 문을 사용하여 ResultBinding에 전달된 값을 검색합니다.

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

참고 항목

작업

방법: 저장 프로시저로 모델 정의(Entity Framework)

개념

ModificationFunctionMapping(EntityTypeMapping)
ModificationFunctionMapping(AssociationSetMapping)
Entity Framework 리소스
Entity Framework 용어
연결 집합을 저장 프로시저에 매핑(Entity Framework)

기타 리소스

EDM 사양
스키마 및 매핑 사양(Entity Framework)
연습: 저장 프로시저에 엔터티 매핑