디자이너 CUD 저장 프로시저
이 단계별 연습에서는 엔터티 형식의 create\insert, update 및 delete(CUD) 작업을 EF 디자이너(Entity Framework Designer)를 사용하여 저장 프로시저에 매핑하는 방법을 보여줍니다. 기본적으로 Entity Framework는 CUD 작업에 대한 SQL 문을 자동으로 생성하지만 저장 프로시저를 이러한 작업에 매핑할 수도 있습니다.
Code First는 저장 프로시저 또는 함수에 대한 매핑을 지원하지 않습니다. 그러나 System.Data.Entity.DbSet.SqlQuery 메서드를 사용하여 저장 프로시저 또는 함수를 호출할 수 있습니다. 예시:
var query = context.Products.SqlQuery("EXECUTE [dbo].[GetAllProducts]");
CUD 작업을 저장 프로시저에 매핑할 때 고려 사항
CUD 작업을 저장 프로시저에 매핑할 때 다음 고려 사항이 적용됩니다.
- CUD 작업 중 하나를 저장 프로시저에 매핑하는 경우 모든 작업을 매핑합니다. 세 작업 모두 매핑하지 않으면 실행 시 매핑되지 않은 작업이 실패하고 UpdateException이 throw됩니다.
- 저장 프로시저의 모든 매개 변수를 엔터티 속성에 매핑해야 합니다.
- 서버에서 삽입된 행에 대한 기본 키 값을 생성하는 경우 이 값을 엔터티의 키 속성에 다시 매핑해야 합니다. 다음 예제에서 InsertPerson 저장 프로시저는 새로 만든 기본 키를 저장 프로시저 결과 집합의 일부로 반환합니다. 기본 키는 EF 디자이너의 <결과 바인딩 추가> 기능을 사용하여 엔터티 키(PersonID)에 매핑됩니다.
- 저장 프로시저 호출은 개념적 모델의 엔터티와 1:1로 매핑됩니다. 예를 들어 개념적 모델에서 상속 계층 구조를 구현한 다음 부모 (기본) 및 자식 (파생) 엔터티에 대한 CUD 저장 프로시저를 매핑하는 경우 자식 변경 내용을 저장하면 자식의 저장 프로시저만 호출되므로 부모의 저장 프로시저 호출이 트리거되지 않습니다.
필수 조건
이 연습을 완료하려면 다음 사항이 필요합니다.
- Visual Studio의 최신 버전.
- School 샘플 데이터베이스.
Project 설정
- Visual Studio 2012를 엽니다.
- 파일-> 새로 만들기 -> 프로젝트를 선택합니다.
- 왼쪽 창에서 Visual C#을 클릭한 다음 콘솔 템플릿을 선택합니다.
- 이름으로 CUDSProcsSample을 입력합니다.
- 확인을 선택합니다.
모델 만들기
솔루션 탐색기에서 프로젝트 이름을 마우스 오른쪽 단추로 클릭하고 추가 -> 새 항목을 선택합니다.
왼쪽 메뉴에서 데이터를 선택한 다음 템플릿 창에서 ADO.NET 엔터티 데이터 모델을 선택합니다.
파일 이름에 CUDSProcs.edmx를 입력하고 추가를 클릭합니다.
모델 콘텐츠 선택 대화 상자에서 데이터베이스에서 생성을 선택한 후 다음을 클릭합니다.
새 연결을 클릭합니다. 연결 속성 대화 상자에서 서버 이름(예: (localdb)\mssqllocaldb)을 입력하고 인증 방법을 선택하고 데이터베이스 이름에 School을 입력한 다음 확인을 클릭합니다. 데이터 연결 선택 대화 상자가 데이터베이스 연결 설정으로 업데이트됩니다.
데이터베이스 개체 선택 대화 상자의 테이블 노드 아래에서 Person 테이블을 선택합니다.
또한 저장 프로시저 및 함수 노드에서 DeletePerson, InsertPerson 및 UpdatePerson의 저장 프로시저를 선택합니다.
Visual Studio 2012부터 EF 디자이너는 저장 프로시저의 일괄 가져오기를 지원합니다. 선택한 저장 프로시저 및 함수를 엔터티 모델로 가져오기는 기본적으로 선택됩니다. 이 예제에서는 엔터티 형식을 삽입, 업데이트 및 삭제하는 저장 프로시저가 있으므로 엔터티 형식을 가져오지 않고 이 확인란의 선택을 취소합니다.
Finish를 클릭합니다. 모델을 편집하기 위한 디자인 화면을 제공하는 EF 디자이너가 표시됩니다.
Person 엔터티를 저장 프로시저에 매핑
Person 엔터티 형식을 마우스 오른쪽 단추로 클릭하고 저장 프로시저 매핑을 선택합니다.
저장 프로시저 매핑이 매핑 세부 정보 창에 나타납니다.
<Insert 함수 선택>을 클릭합니다. 필드가 스토리지 모델의 저장 프로시저를 포함하는 드롭다운 목록이 됩니다. 이 목록의 저장 프로시저를 개념적 모델의 엔터티 형식에 매핑할 수 있습니다. 드롭다운 목록에서 InsertPerson을 선택합니다.
저장 프로시저 매개 변수와 엔터티 속성 간의 기본 매핑이 나타납니다. 화살표는 매핑 방향을 나타냅니다. 즉, 속성 값이 저장 프로시저 매개 변수에 제공됩니다.
<결과 바인딩 추가>를 클릭합니다.
InsertPerson 저장 프로시저에서 반환된 매개 변수의 이름인 NewPersonID를 입력합니다. 선행 또는 후행 공백을 입력하지 않도록 합니다.
Enter 키를 누릅니다.
기본적으로 NewPersonID는 엔터티 키 PersonID에 매핑됩니다. 화살표는 매핑 방향을 나타냅니다. 즉, 결과 열의 값이 속성에 제공됩니다.
<Update 함수 선택>을 클릭하고 결과 드롭다운 목록에서 UpdatePerson을 선택합니다.
저장 프로시저 매개 변수와 엔터티 속성 간의 기본 매핑이 나타납니다.
<Delete 함수 선택>을 클릭하고 결과 드롭다운 목록에서 DeletePerson을 선택합니다.
저장 프로시저 매개 변수와 엔터티 속성 간의 기본 매핑이 나타납니다.
이제 Person 엔터티 형식의 삽입, 업데이트, 삭제 작업이 저장 프로시저에 매핑되었습니다.
저장 프로시저를 사용하여 엔터티를 업데이트하거나 삭제할 때 동시성 검사를 사용하도록 설정하려면 다음 옵션 중 하나를 사용합니다.
- OUTPUT 매개 변수를 사용하여 저장 프로시저에서 영향을 받는 행 수를 반환하고 매개 변수 이름 옆에 있는 영향을 받는 행 매개 변수 확인란을 선택합니다. 작업이 호출될 때 반환된 값이 0이면 OptimisticConcurrencyException이 throw됩니다.
- 동시성 검사에 사용할 속성 옆에 있는 원래 값 사용 확인란을 선택합니다. 업데이트를 시도하면 데이터를 다시 데이터베이스에 쓸 때 원래 데이터베이스에서 읽은 속성의 값이 사용됩니다. 값이 데이터베이스의 값과 일치하지 않으면 OptimisticConcurrencyException이 throw됩니다.
모델 사용
Main 메서드가 정의된 Program.cs 파일을 엽니다. Main 함수에 다음 코드를 추가합니다.
코드는 새 Person 개체를 만든 다음 개체를 업데이트하고 마지막으로 개체를 삭제합니다.
using (var context = new SchoolEntities())
{
var newInstructor = new Person
{
FirstName = "Robyn",
LastName = "Martin",
HireDate = DateTime.Now,
Discriminator = "Instructor"
}
// Add the new object to the context.
context.People.Add(newInstructor);
Console.WriteLine("Added {0} {1} to the context.",
newInstructor.FirstName, newInstructor.LastName);
Console.WriteLine("Before SaveChanges, the PersonID is: {0}",
newInstructor.PersonID);
// SaveChanges will call the InsertPerson sproc.
// The PersonID property will be assigned the value
// returned by the sproc.
context.SaveChanges();
Console.WriteLine("After SaveChanges, the PersonID is: {0}",
newInstructor.PersonID);
// Modify the object and call SaveChanges.
// This time, the UpdatePerson will be called.
newInstructor.FirstName = "Rachel";
context.SaveChanges();
// Remove the object from the context and call SaveChanges.
// The DeletePerson sproc will be called.
context.People.Remove(newInstructor);
context.SaveChanges();
Person deletedInstructor = context.People.
Where(p => p.PersonID == newInstructor.PersonID).
FirstOrDefault();
if (deletedInstructor == null)
Console.WriteLine("A person with PersonID {0} was deleted.",
newInstructor.PersonID);
}
- 애플리케이션을 컴파일하고 실행합니다. 프로그램에서는 다음이 출력됩니다.*
참고 항목
PersonID는 서버에서 자동으로 생성되므로 다른 숫자가 표시될 가능성이 높습니다.*
Added Robyn Martin to the context.
Before SaveChanges, the PersonID is: 0
After SaveChanges, the PersonID is: 51
A person with PersonID 51 was deleted.
Visual Studio의 Ultimate 버전으로 작업하는 경우 디버거와 함께 Intellitrace를 사용하여 실행되는 SQL 문을 볼 수 있습니다.
.NET