逐步解說:使用型別提供者和實體存取 SQL 資料庫 (F#)
F# 的 3.0 這個逐步解說會示範如何存取具型別的資料 (根據 ADO.NET 實體資料模型的 SQL 資料庫)。 這個逐步解說會示範如何設定 SqlEntityConnection F# 型別的提供者來使用SQL 資料庫,以及如何撰寫對資料的查詢,如何呼叫資料庫中的預存程序,以及如何使用特定 ADO.NET Entity Framework 型別和方法來更新資料庫。
這個逐步解說將說明下列工作,您應該在這個逐步解說的這個順序執行才會成功:
建立 School 資料庫。 .
建立並設定一個 F# 專案 .
設定這個型別的提供者,並連接至實體資料模型 .
查詢資料庫 .
更新資料庫
必要條件
您必須可以存取執行 SQL Server 好讓您可以建立資料庫伺服器來完成這些步驟。
建立 School 資料庫。
您可以執行 SQL Server 來存取系統管理的所有伺服器上的 School 資料庫,也可以使用 LocalDB。
建立 School 資料庫。
在 [伺服器總管] 中,在[資料連結] 上按一下滑鼠右鍵,然後在捷徑功能表中選擇 [修改連接]。
[加入連接] 對話方塊隨即出現。
在 伺服器名稱 中,為您已經能夠存取的SQL伺服器指定一個名稱或者你還沒存取任何資料庫,將它指定為 (localdb\v11.0).
SQL Server Express LocalDB 用於開發提供輕量型資料庫伺服器和測試電腦。 如需LocalDB的詳細資訊,請參閱逐步解說:建立 LocalDB 資料庫。
新連接已經建立並顯示在 [伺服器總管] 中的 [資料連接] 底下。
打開捷徑工具列選擇新連線然後選擇新查詢
開啟 建立學校範例資料庫。 Microsoft 網站,然後複製並貼上建立學生資料庫進入編輯視窗的資料庫指令碼。
在這個逐步解說中的後續步驟請參閱下列教學課程: ADO.NET Entity Data Model Quickstart。
建立並設定一個 F# 專案
在這個步驟中,您會建立專案並將其設定為使用型別的提供者。
建立和設定 F# 專案
結束先前專案,建立另一個專案,並命名為 SchoolEDM。
在 [方案總管] 中按一下 [參考],然後在捷徑功能表中按一下 [加入參考]。
選擇 Framework 選項,然後在Framework 列表中選擇System.Data, System.Data.Entity,以及System.Data.Linq.
選擇 Extensions 選項,加入一個reference到 FSharp.Data.TypeProviders ,然後點選OK 來關掉對話窗.
加入下列程式碼以定義一個內部模組和開啟適當的命名空間。 這種提供者只能插入型別的私用或內部命名空間。
module internal SchoolEDM open System.Data.Linq open System.Data.Entity open Microsoft.FSharp.Data.TypeProviders
為了在這個逐步解說中互動性的以指令碼而不是編譯過的程式來執行程式碼, 打開捷徑工具列的project node,選擇加入一個新物件 ,加入一個F#的指令碼檔案,然後在指令碼的每個步驟中加入程式碼. 若要載入組件參考,加入下列程式碼行。
#r "System.Data.Entity.dll" #r "FSharp.Data.TypeProviders.dll" #r "System.Data.Linq.dll"
在 F# Interactive 反白顯示程式碼的每個區塊,並按下 Alt + Enter 鍵執行它。
設定這個型別的提供者,並連接至實體資料模型
在這個步驟中,您將使用資料連接的一種提供者和取得可讓您使用資料的資料內容。
設定這個型別的提供者,並連接至實體資料模型
輸入下列程式碼將來調整會建立您先前創造的Entity Data Model 之F#型別的 SqlEntityConnection 型別提供者。 請使用 SQL 連接字串,而非完整的 EDMX 連接字串。
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 程式碼中常常出現。 如需詳細資訊,請參閱 Multiple Active Result Set (MARS)。
取得資料內容,這些物件都包含資料庫資料表做為屬性和資料庫預存程序和函式做為方法。
let context = EntityConnection.GetDataContext()
查詢資料庫
在這個步驟中,您使用 F# 查詢運算式在資料庫上執行各種查詢。
查詢資料。
輸入下列程式碼會查詢將實體資料模型中的資料。 請注意 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)
更新資料庫
若要更新資料庫,可以使用 Entity Framework 類別和方法。 您可以使用資料內容的兩種型別搭配上 SQLEntityConnection 型別的功能提供者。 首先, ServiceTypes.SimpleDataContextTypes.EntityContainer 是簡化的資料內容,只提供屬性來表示資料庫資料表和資料行。 接著,完整資料內容是 Entity Framework ObjectContext類別的執行個體,其中包含這個方法 AddObject 將資料列加入至資料庫。 Entity Framework 辨識資料表和這些資料表之間關聯性 (Relationship),因此,強制資料庫一致。
若要更新資料庫
將下列程式碼加入您的程式。 在這個範例中,加入具有關聯性的兩個物件,並且加入一行 Instructor 和一個 Office 工作。 資料表 OfficeAssignments 包含 InstructorID 欄位,在 Person 表格中參考 PersonID 欄位。
// 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#)