Wskazówki: uzyskiwanie dostępu do bazy danych SQL za pomocą dostawców typów i jednostek (F#)
W tym przewodniku dotyczącym języka F# 3.0 pokazano, w jaki sposób można uzyskać dostęp do danych mających określony typ w bazie danych SQL opartej na modelu Entity Data Model programu ADO.NET.W tym przewodniku pokazano, w jaki sposób skonfigurować dostawcę typów SqlEntityConnection języka F# do działania z bazą danych SQL, jak pisać zapytania dotyczące danych, jak wywoływać procedury składowane w bazie danych, oraz w jaki sposób używać niektórych typów i metod programu ADO.NET Entity Framework, aby zaktualizować bazę danych.
W tym przewodniku opisano następujące zadania, które trzeba wykonać, aby pomyślnie przerobić przewodnik:
Utworzenie bazy danych School.
Utworzenie i skonfigurowanie projektu języka F#.
Skonfigurowanie dostawcy typów i nawiązanie połączenia z modelem Entity Data Model.
Wykonanie zapytania w bazie danych.
Zaktualizowanie bazy danych.
Wymagania wstępne
Aby wykonać te kroki, trzeba mieć dostęp do serwera, na którym działa program SQL Server umożliwiający utworzenie bazy danych.
Utworzenie bazy danych School
Bazę danych School możesz utworzyć na dowolnym serwerze, na którym działa program SQL Server i do którego masz dostęp administracyjny, ale możesz też użyć programu LocalDB.
Aby utworzyć bazę danych School
W Eksploratorze serwera otwórz menu skrótów węzła Połączenia danych, a następnie wybierz polecenie Dodaj połączenie.
Zostanie wyświetlone okno dialogowe Dodaj połączenie.
W polu Nazwa serwera określ nazwę wystąpienia programu SQL Server, do którego masz dostęp administracyjny lub, jeśli nie masz dostępu do serwera, określ nazwę (localdb\v11.0).
Program SQL Server Express LocalDB dostarcza uproszczony serwer bazy danych, którego można używać na potrzeby tworzenia i testowania na swoim komputerze.Aby uzyskać więcej informacji dotyczących programu LocalDB, zobacz Wskazówki: tworzenie lokalnego pliku bazy danych w programie Visual Studio.
Nowy węzeł zostanie utworzony w Eksploratorze serwera w węźle Połączenia danych.
Otwórz menu skrótów nowego węzła połączenia, a następnie wybierz polecenie Nowe zapytanie.
Otwórz artykuł Tworzenie przykładowej bazy danych School w witrynie sieci Web firmy Microsoft, a następnie skopiuj i wklej do okna edytora skrypt, który tworzy bazę danych o nazwie Student.
Utworzenie i skonfigurowanie projektu języka F#
W tym kroku należy utworzyć projekt i skonfigurować go do używania dostawcy typów.
Aby utworzyć i skonfigurować projekt języka F#
Zamknij poprzedni projekt i utwórz nowy projekt o nazwie SchoolEDM.
W oknie Eksplorator rozwiązań otwórz menu skrótów pozycji Odwołania, a następnie wybierz polecenie Dodaj odwołanie.
Wybierz węzeł Framework, a następnie z listy Framework wybierz pozycje System.Data, System.Data.Entity i System.Data.Linq.
Wybierz węzeł Rozszerzenia, dodaj odwołanie do zestawu FSharp.Data.TypeProviders, a następnie kliknij przycisk OK, aby zamknąć okno dialogowe.
Dodaj następujący kod, aby zdefiniować moduł wewnętrzny i otworzyć odpowiednie przestrzenie nazw.Dostawca typów może wprowadzać typy tylko do prywatnej lub wewnętrznej przestrzeni nazw.
module internal SchoolEDM open System.Data.Linq open System.Data.Entity open Microsoft.FSharp.Data.TypeProviders
Aby kod z tego przewodnika uruchomić interakcyjnie jako skrypt, a nie jako skompilowany program, otwórz menu skrótów węzła projektu, wybierz polecenie Dodaj nowy element, dodaj plik skryptu języka F#, a następnie dodawaj do skryptu kod tworzony w każdym kroku przewodnika.Aby załadować odwołania do zestawu, dodaj następujące wiersze.
#r "System.Data.Entity.dll" #r "FSharp.Data.TypeProviders.dll" #r "System.Data.Linq.dll"
Wyróżnij każdy blok kodu, który dodajesz, i użyj klawiszy Alt+Enter, aby uruchomić go w interakcyjnej wersji języka F#.
Skonfigurowanie dostawcy typów i nawiązanie połączenia z modelem Entity Data Model
W tym kroku należy skonfigurować dostawcę typów z połączeniem danych i uzyskać kontekst danych, który umożliwi pracę z danymi.
Aby skonfigurować dostawcę typów i nawiązać połączenie z modelem Entity Data Model
Wprowadź następujący kod, aby skonfigurować dostawcę typów SqlEntityConnection, który wygeneruje typy języka F# na podstawie utworzonego uprzednio modelu Entity Data Model.Zamiast pełnych parametrów połączenia EDMX, użyj jedynie parametrów połączenia SQL.
type private EntityConnection = SqlEntityConnection<ConnectionString="Server=SERVER\InstanceName;Initial Catalog=School;Integrated Security=SSPI;MultipleActiveResultSets=true", Pluralize = true> >
Ta akcja konfiguruje dostawcę typów z połączeniem z bazą danych, które zostało utworzone wcześniej.Właściwość MultipleActiveResultSets jest wymagana, gdy jest używany program ADO.NET Entity Framework, ponieważ ta właściwość umożliwia asynchroniczne wykonywanie wielu poleceń w bazie danych w ramach jednego połączenia, co może często występować w kodzie opartym na programie ADO.NET Entity Framework.Aby uzyskać więcej informacji, zobacz Wiele aktywnych zestawów wyników (MARS).
Pobierz kontekst danych, który jest obiektem zawierającym tabele bazy danych jako właściwości oraz procedury składowane i funkcje bazy danych jako metody.
let context = EntityConnection.GetDataContext()
Wykonywanie zapytania w bazie danych
W tym kroku należy użyć wyrażeń zapytania języka F#, aby wykonać różne zapytania w bazie danych.
Aby wykonać zapytanie dotyczące danych
Wprowadź następujący kod, aby utworzyć zapytanie dotyczące danych w modelu Entity Data Model.Należy zwrócić uwagę na efekt działania właściwości Pluralize = true, która powoduje zmianę nazw tabel bazy danych z Course na Courses i z Person na People.
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)
Zaktualizowanie bazy danych
Aby zaktualizować bazę danych, należy użyć klas i metod programu Entity Framework.Z dostawcą typów SQLEntityConnection można używać dwóch typów kontekstu danych.Pierwszy, ServiceTypes.SimpleDataContextTypes.EntityContainer, to uproszczony kontekst danych, który zawiera tylko dostarczone właściwości reprezentujące tabele i kolumny bazy danych.Drugi, pełny kontekst danych, to wystąpienie klasy ObjectContext programu Entity Framework, która zawiera metodę AddObject służącą do dodawania wierszy do bazy danych.Program Entity Framework rozpoznaje tabele i relacje między nimi, a więc wymusza spójność bazy danych.
Aby zaktualizować bazę danych
Dodaj poniższy kod do programu.W tym przykładzie należy dodać dwa obiekty powiązane relacją, a następnie należy dodać instruktora oraz przypisane biuro.Tabela OfficeAssignments zawiera kolumnę InstructorID, która odwołuje się do kolumny PersonID w tabeli Person.
// 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")
Nic nie zostanie zmienione w bazie danych, dopóki nie zostanie wywołana metoda SaveChanges.
Teraz przywróć bazę danych do wcześniejszego stanu, usuwając obiekty, które zostały dodane.
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")
Przestroga Gdy jest używane wyrażenie zapytania, musisz pamiętać, że zapytanie jest obliczane z opóźnieniem.Z tego powodu baza danych pozostaje otwarta do odczytu podczas dowolnych obliczeń łańcuchowych, takich jak bloki wyrażenia lambda po każdym wyrażeniu zapytania.Dowolna operacja w bazie danych, która jawnie lub niejawnie używa transakcji, musi nastąpić po zakończeniu operacji odczytu.
Następne kroki
Poznaj inne opcje zapytań, przeglądając operatory zapytania opisane w artykule Wyrażenia kwerend (F#), a także przejrzyj artykuł ADO.NET Entity Framework, aby dowiedzieć się, jakie funkcje są dostępne podczas korzystania z tego dostawcy typów.
Zobacz też
Zadania
Wskazówki: generowanie typów F# za pomocą pliku schematu EDMX (F#)
Informacje
SqlEntityConnection — Typ dostawcy (F#)