연습: 형식 공급자 및 엔터티를 사용하여 SQL 데이터베이스에 액세스(F#)
F# 3.0에 대한 이 연습에서는 ADO.NET 엔티티 데이터 모델을 기반으로 SQL 데이터베이스에 대해 형식화된 데이터에 액세스하는 방법을 보여 줍니다.이 연습에서는 SQL 데이터베이스를 사용하여 F# SqlEntityConnection 형식 공급자를 설정하는 방법, 데이터에 대해 쿼리를 작성하는 방법, 데이터베이스에 저장된 프로시저를 호출하는 방법과 ADO.NET Entity Framework 형식 및 메서드 중 일부를 사용하여 데이터베이스를 업데이트하는 방법을 보여줍니다.
이 연습에서는 다음 작업을 보여 줍니다. 이 경우 연습을 성공적으로 수행하기 위해 이 순서대로 수행해야 합니다.
학교 데이터베이스를 만듭니다..
F# 프로젝트를 만들고 구성합니다..
형식 공급자를 구성하고 엔터티 데이터 모델에 연결합니다..
데이터베이스를 쿼리하고 있습니다..
데이터베이스 업데이트
사전 요구 사항
이러한 단계를 완료하려면 데이터베이스를 만들 수 있는 SQL 서버를 실행하는 서버에 액세스할 수 있어야 합니다.
학교 데이터베이스를 만듭니다.
관리자 액세스 권한을 가진 SQL Server를 실행하는 서버에 School 데이터베이스를 만들거나 LocalDB를 사용할 수 있습니다.
School 데이터베이스 만들기
서버 탐색기에서 데이터 연결 노드에 대한 바로 가기 메뉴를 연 다음 연결 추가를 선택합니다.
연결 추가 대화 상자가 나타납니다.
서버 이름 상자에서 관리 액세스 권한이 있는 SQL Server의 인스턴스 이름을 지정 하거나 서버에 액세스할 수 없는 경우 (localdb\v11.0)을 지정합니다.
SQL Server Express LocalDB는 사용자 시스템에서 개발 및 테스트를 위한 단순화된 데이터베이스 서버를 제공합니다.LocalDB에 대한 자세한 내용은 연습: LocalDB 데이터베이스 만들기를 참조하십시오.
데이터 연결 아래의 서버 탐색기에 새 노드가 만들어집니다.
새 연결 노드의 바로 가기 메뉴를 열고 새 쿼리를 선택합니다.
Microsoft 웹 사이트에서 School 샘플 데이터베이스 만들기를 연 다음 Student 데이터베이스를 만드는 데이터베이스 스크립트를 복사하여 편집기 창에 붙여 넣습니다.
이 연습의 다음 단계는 ADO.NET Entity Data Model Quickstart 자습서를 기반으로 합니다.
F# 프로젝트를 만들고 구성합니다.
이 단계에서 형식 공급자를 사용하려면 프로젝트를 만들고 설정합니다.
F# 프로젝트를 만들고 구성하는 방법
이전 프로젝트를 닫고 SchoolEDM이라는 새 프로젝트를 만듭니다.
솔루션 탐색기에서 참조의 바로 가기 메뉴를 열고 참조 추가를 선택합니다.
Framework 노드를 선택한 다음 Framework 목록에서 System.Data, System.Data.Entity 및 System.Data.Linq를 선택합니다.
확장 노드를 선택하고, 참조를 FSharp.Data.TypeProviders 어셈블리에 추가한 후, 확인 단추를 선택하여 대화 상자를 닫습니다.
다음 코드를 추가하여 내부 모듈을 정의하고 적절한 네임스페이스를 엽니다.형식 공급자는 형식을 private 또는 internal 네임스페이스로만 주입할 수 있습니다.
module internal SchoolEDM open System.Data.Linq open System.Data.Entity open Microsoft.FSharp.Data.TypeProviders
이 연습에서 컴파일된 프로그램 대신 스크립트로 대화형으로 코드를 실행하려면 프로젝트 노드에 대한 바로 가기 메뉴를 열고 새 항목 추가를 선택하고 F# 스크립트 파일을 추가한 다음 각 단계의 코드를 스크립트에 추가합니다.어셈블리 참조를 로드하려면 다음 줄을 추가합니다.
#r "System.Data.Entity.dll" #r "FSharp.Data.TypeProviders.dll" #r "System.Data.Linq.dll"
추가한 코드 블록을 강조하고 F# Interactive에서 Alt + Enter 키를 눌러 강조된 블록을 실행할 수 있습니다.
형식 공급자를 구성하고 엔터티 데이터 모델에 연결합니다.
이 단계에서 데이터 연결을 사용하여 형식 공급자를 설정하고 데이터로 작업할 수 있는 데이터 컨텍스트를 가져옵니다.
형식 공급자를 구성하고 엔터티 데이터 모델에 연결하려면
다음 코드를 입력하여 이전에 사용자가 만든 엔터티 데이터 모델을 기반으로 F# 형식을 생성하는 SqlEntityConnection 형식 공급자를 구성합니다.전체 EDMX 연결 문자열 대신 SQL 연결 문자열만 사용합니다.
type private EntityConnection = SqlEntityConnection<ConnectionString="Server=SERVER\InstanceName;Initial Catalog=School;Integrated Security=SSPI;MultipleActiveResultSets=true", Pluralize = true> >
이 작업을 통해 앞에서 만든 데이터베이스 연결을 사용하는 형식 공급자가 설정됩니다.속성 MultipleActiveResultSets는 이 속성이 한 연결로 데이터베이스에서 비동기적으로 여러 명령을 실행할 수 있기 때문에 ADO.NET Entity Framework를 사용할 때 필요하며, 이는 ADO.NET Entity Framework 코드에서 자주 발생할 수 있습니다.자세한 내용은 MARS(Multiple Active Result Sets를 참조하십시오.
데이터베이스 테이블을 속성으로 포함하고 데이터베이스 저장 프로시저와 함수를 메서드로 포함하는 개체인 데이터 컨텍스트를 가져옵니다.
let context = EntityConnection.GetDataContext()
데이터베이스를 쿼리하고 있습니다.
이 단계에서는 F# 쿼리 식을 사용하여 데이터베이스에서 다양한 쿼리를 실행합니다.
데이터에 쿼리하는 방법
엔터티 데이터 모델의 데이터를 쿼리하려면 다음 코드를 입력합니다.데이터베이스 테이블 Course를 Courses로, Person을 People로 변경하는 Pluralize = true의 효과에 유의하십시오.
query { for course in context.Courses do select course } |> Seq.iter (fun course -> printfn "%s" course.Title) query { for person in context.People do select person } |> Seq.iter (fun person -> printfn "%s %s" person.FirstName person.LastName) // Add a where clause to filter results. query { for course in context.Courses do where (course.DepartmentID = 1) select course } |> Seq.iter (fun course -> printfn "%s" course.Title) // Join two tables. query { for course in context.Courses do join dept in context.Departments on (course.DepartmentID = dept.DepartmentID) select (course, dept.Name) } |> Seq.iter (fun (course, deptName) -> printfn "%s %s" course.Title deptName)
데이터베이스 업데이트
데이터베이스를 업데이트하려면 엔터티 프레임워크 클래스와 메서드를 사용합니다.두 가지 형식의 데이터 컨텍스트를 SQLEntityConnection 형식 공급자와 함께 사용할 수 있습니다.첫째 ServiceTypes.SimpleDataContextTypes.EntityContainer는 데이터베이스 테이블과 열을 나타내는 제공된 속성만 포함하는 간단한 데이터 컨텍스트입니다.둘째, 전체 데이터 컨텍스트는 데이터베이스에 행을 추가하기 위해 메서드 AddObject을 포함하는 Entity Framework 클래스 ObjectContext의 인스턴스입니다.엔터티 프레임워크는 테이블과 이 테이블 사이의 관계를 인식하므로 데이터베이스 일관성이 적용됩니다.
데이터베이스를 업데이트하려면
프로그램에 다음 코드를 추가합니다.이 예제에서 두 개체 간에 관계를 추가하고 강사 및 사무실 할당을 추가합니다.테이블 OfficeAssignments에는 Person 테이블의 PersonID 열을 참조하는 InstructorID이 포함되어 있습니다.
// The full data context let fullContext = context.DataContext // A helper function. let nullable value = new System.Nullable<_>(value) let addInstructor(lastName, firstName, hireDate, office) = let hireDate = DateTime.Parse(hireDate) let newPerson = new EntityConnection.ServiceTypes.Person(LastName = lastName, FirstName = firstName, HireDate = nullable hireDate) fullContext.AddObject("People", newPerson) let newOffice = new EntityConnection.ServiceTypes.OfficeAssignment(Location = office) fullContext.AddObject("OfficeAssignments", newOffice) fullContext.CommandTimeout <- nullable 1000 fullContext.SaveChanges() |> printfn "Saved changes: %d object(s) modified." addInstructor("Parker", "Darren", "1/1/1998", "41/3720")
SaveChanges를 호출할 때까지 데이터베이스에서 변경된 사항이 없습니다.
이제 추가한 개체를 삭제하여 데이터베이스를 이전 상태로 복원합니다.
let deleteInstructor(lastName, firstName) = query { for person in context.People do where (person.FirstName = firstName && person.LastName = lastName) select person } |> Seq.iter (fun person-> query { for officeAssignment in context.OfficeAssignments do where (officeAssignment.Person.PersonID = person.PersonID) select officeAssignment } |> Seq.iter (fun officeAssignment -> fullContext.DeleteObject(officeAssignment)) fullContext.DeleteObject(person)) // The call to SaveChanges should be outside of any iteration on the queries. fullContext.SaveChanges() |> printfn "Saved changed: %d object(s) modified." deleteInstructor("Parker", "Darren")
주의 쿼리 식을 사용하는 경우 쿼리에서 평가가 지연될 수 있음을 기억해야 합니다.따라서 데이터베이스는 각 쿼리 식 다음에 lambda 식 블록에서처럼 연결된 평가 동안 읽기 위해 엽니다.명시적 또는 묵시적으로 트랜잭션을 사용하는 데이터베이스 작업은 읽기 작업이 완료된 후에 발생해야 합니다.
다음 단계
쿼리 식(F#)에서 사용할 수 있는 쿼리 연산자를 검토하여 다른 쿼리 옵션을 찾아보고 ADO.NET Entity Framework를 검토하여 이 형식 공급자를 사용할 때 어떤 기능을 이용할 수 있는지 이해합니다.
참고 항목
작업
연습: EDMX 스키마 파일에서 F# 형식 생성(F#)
참조
SqlEntityConnection 형식 공급자(F#)