Exemplarische Vorgehensweise: Zugreifen auf eine SQL-Datenbank mithilfe von Typanbietern und Entitäten (F#)
In dieser exemplarischen Vorgehensweise für F# 3.0 wird gezeigt, wie Sie auf typisierte Daten einer SQL-Datenbank zugreifen, die auf dem ADO.NET Entity Data Model basiert.In der exemplarischen Vorgehensweise wird erläutert, wie Sie den F#-Typanbieter SqlEntityConnection zur Verwendung mit einer SQL-Datenbank einrichten, wie Sie Datenabfragen schreiben, gespeicherte Prozeduren in der Datenbank aufrufen und wie einige der ADO.NET Entity Framework-Typen und -Methoden verwendet werden, um die Datenbank zu aktualisieren.
Die exemplarische Vorgehensweise veranschaulicht die folgenden Aufgaben, die Sie in der angegebenen Reihenfolge ausführen müssen, um die exemplarische Vorgehensweise erfolgreich abzuschließen:
Erstellen der Datenbank "School"..
Erstellen und Konfigurieren eines F#-Projekts.
Konfigurieren des Typanbieters und Verbinden mit dem Entity Data Model.
Abfragen der Datenbank.
Aktualisieren der Datenbank
Vorbereitungsmaßnahmen
Zum Abschließen dieser Schritte benötigen Sie Zugriff auf einen SQL Server, auf dem Sie eine Datenbank erstellen können.
Erstellen der Datenbank "School".
Sie können die Datenbank School auf jedem Server erstellen, auf dem SQL Server ausgeführt wird und auf den Sie administrativen Zugriff haben, oder Sie können LocalDB verwenden.
So erstellen Sie die Datenbank School
Öffnen Sie im Server-Explorer das Kontextmenü für den Knoten Datenverbindungen, und wählen Sie dann Verbindung hinzufügen.
Das Dialogfeld Verbindung hinzufügen wird angezeigt.
Im Feld Servername geben Sie den Namen einer Instanz von SQL Server an, auf die Sie administrativen Zugriff haben. Wenn Sie keinen Zugriff auf einen Server haben, geben Sie an (localdb\v11.0) ein.
SQL Server Express LocalDB stellt einen einfachen Datenbankserver für Entwicklung und Tests auf dem Computer bereit.Weitere Informationen über LocalDB finden Sie unter Exemplarische Vorgehensweise: Erstellen einer LocalDB-Datenbank.
Ein neuer Knoten wird in Server-Explorer unter Datenverbindungen erstellt.
Öffnen Sie das Kontextmenü für den neuen Verbindungsknoten, und wählen Sie dann Neue Abfrage.
Öffnen Sie Erstellen der Beispieldatenbank "School" auf der Microsoft-Website, kopieren Sie das Datenbankskript zum Erstellen der Studierendendatenbank, und fügen Sie es in das Editorfenster ein.
Die nächsten Schritte in dieser exemplarischen Vorgehensweise basieren auf dem folgenden Lernprogramm: ADO.NET Entity Data Model Quickstart.
Erstellen und Konfigurieren eines F#-Projekts
In diesem Schritt erstellen Sie ein Projekt, das einen Typanbieter verwendet.
So erstellen und konfigurieren Sie ein F#-Projekt
Schließen Sie das vorherige Projekt und erstellen Sie ein neues Projekt mit dem Namen SchoolEDM.
Öffnen Sie im Projektmappen-Explorer das Kontextmenü für Verweise, und wählen Sie Verweis hinzufügen aus.
Wählen Sie den Knoten Framework. In der Liste Framework wählen Sie dann System.Data, System.Data.Entity und System.Data.Linq.
Wählen Sie den Knoten Erweiterungen, fügen Sie einen Verweis auf die FSharp.Data.TypeProviders-Assembly hinzu, und wählen Sie dann die Schaltfläche OK, um das Dialogfeld zu schließen.
Fügen Sie den folgenden Code hinzu, um ein internes Modul zu definieren und entsprechende Namespaces zu öffnen.Der Typanbieter kann Typen nur in einen privaten oder einen internen Namespace einfügen.
module internal SchoolEDM open System.Data.Linq open System.Data.Entity open Microsoft.FSharp.Data.TypeProviders
Um den Code in dieser exemplarischen Vorgehensweise interaktiv als Skript und nicht als kompiliertes Programm auszuführen, öffnen Sie das Kontextmenü für den Projektknoten, wählen Neues Element hinzufügen, fügen eine F#-Skriptdatei hinzu, und fügen dem Skript dann den Code in jedem Schritt hinzu.Zum Laden der Assemblyverweise müssen Sie die folgenden Zeilen hinzufügen.
#r "System.Data.Entity.dll" #r "FSharp.Data.TypeProviders.dll" #r "System.Data.Linq.dll"
Heben Sie jeden Codeblock beim Hinzufügen hervor und wählen Sie die Tasten ALT+EINGABE, um ihn in F# Interactive auszuführen.
Konfigurieren des Typanbieters und Verbinden mit dem Entity Data Model
In diesem Schritt richten Sie einen Typanbieter mit einer Datenverbindung ein und erhalten einen Datenkontext, der Ihnen die Arbeit mit Daten ermöglicht.
So konfigurieren Sie den Typanbieter und stellen eine Verbindung mit dem Entity Data Model her
Geben Sie den folgenden Code ein, um den SqlEntityConnection-Typanbieter zu konfigurieren, der F#-Typen basierend auf dem zuvor erstellten Entity Data Model generiert.Verwenden Sie anstelle der vollständigen EDMX-Verbindungszeichenfolge nur die SQL-Verbindungszeichenfolge.
type private EntityConnection = SqlEntityConnection<ConnectionString="Server=SERVER\InstanceName;Initial Catalog=School;Integrated Security=SSPI;MultipleActiveResultSets=true", Pluralize = true> >
Mit diesem Vorgang wird ein Typanbieter mit der zuvor erstellten Datenbankverbindung eingerichtet.Die MultipleActiveResultSets-Eigenschaft ist erforderlich, wenn Sie das ADO.NET Entity Framework verwenden, da diese Eigenschaft die asynchrone, gleichzeitige Ausführung mehrerer Datenbankbefehle in einer Verbindung ermöglicht und dieser Fall in ADO.NET Entity Framework-Code häufig auftritt.Weitere Informationen finden Sie unter Verwenden von Multiple Active Result Sets (MARS).
Rufen Sie den Datenkontext ab. Dies ist ein Objekt, das die Datenbanktabellen als Eigenschaften und die gespeicherten Prozeduren und Funktionen der Datenbank als Methoden enthält.
let context = EntityConnection.GetDataContext()
Abfragen der Datenbank
In diesem Schritt verwenden Sie F#-Abfrageausdrücke, um verschiedene Abfragen in der Datenbank auszuführen.
So fragen Sie Daten ab
Geben Sie den folgenden Code ein, um Daten aus dem Entity Data Model abzufragen.Beachten Sie die Auswirkungen von Pluralize = true: Die Datenbanktabelle Course wird in Courses, und Person wird in People geändert.
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)
Aktualisieren der Datenbank
Zum Aktualisieren der Datenbank verwenden Sie die Entity Framework-Klassen und -Methoden.Sie können zwei Typen von Datenkontexten für den SQLEntityConnection-Typanbieter verwenden.Der erste ist der vereinfachte Datenkontext ServiceTypes.SimpleDataContextTypes.EntityContainer, der nur die Eigenschaften bereitstellt, die die Datenbanktabellen und -spalten darstellen.Der zweite, vollständige Datenkontext ist eine Instanz der Entity Framework-Klasse ObjectContext, die die Methode AddObject enthält, um Zeilen zur Datenbank hinzuzufügen.Das Entity Framework erkennt die Tabellen und die Beziehungen zwischen ihnen, sodass die Datenbankkonsistenz erzwungen wird.
So aktualisieren Sie die Datenbank
Fügen Sie dem Programm folgenden Code hinzu.In diesem Beispiel fügen Sie zwei Objekte mit einer gegenseitigen Beziehung sowie eine Lehrkraft- und eine Bürozuweisung hinzu.Die Tabelle OfficeAssignments enthält die Spalte InstructorID, die auf die Spalte PersonID in der Tabelle Person verweist.
// 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")
In der Datenbank werden erst dann Änderungen vorgenommen, wenn Sie SaveChanges aufrufen.
Löschen Sie jetzt die Objekte, die Sie hinzugefügt haben, um den ursprünglichen Zustand der Datenbank wiederherzustellen.
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")
Vorsicht Wenn Sie einen Abfrageausdruck verwenden, denken Sie daran, dass Abfragen verzögert ausgewertet werden.Die Datenbank bleibt daher bei allen verketteten Auswertungen zum Lesen geöffnet, so z. B. auch während der Verarbeitung der Lambda-Ausdrucksblöcke nach jedem Abfrageausdruck.Jeder Datenbankvorgang, der explizit oder implizit eine Transaktion verwendet, darf erst erfolgen, wenn die Lesevorgänge abgeschlossen sind.
Nächste Schritte
Studieren Sie weitere Abfrageoptionen, indem Sie sich mit den verfügbaren Abfrageoperatoren unter Abfrageausdrücke (F#) vertraut machen, und lesen Sie die Informationen unter ADO.NET Entity Framework, um besser zu verstehen, welche Funktionen bei der Verwendung dieses Typanbieters verfügbar sind.
Siehe auch
Aufgaben
Exemplarische Vorgehensweise: Generieren von F#-Typen aus einer EDMX-Schemadatei (F#)
Referenz
SqlEntityConnection-Typanbieter (F#)