Procedura dettagliata: accesso a un database SQL tramite entità e provider di tipi (F#)
Questa procedura dettagliata per F# 3.0 illustra come accedere ai dati tipizzati per un database SQL basato su ADO.NET Entity Data Model. In questa procedura dettagliata viene illustrato come configurare il provider di tipi SqlEntityConnection di F# per l'utilizzo con un database SQL, come scrivere query sui dati, ad esempio stored procedure nel database, e come utilizzare alcuni dei tipi e dei metodi di ADO.NET Entity Framework per aggiornare il database.
In questa procedura dettagliata vengono illustrate le seguenti attività, che è consigliabile eseguire in quest'ordine perché la procedura abbia esito positivo:
Creare il database School.
Creare e configurare un progetto F#.
Configurare il provider di tipi e connettersi a Entity Data Model.
Eseguire query sul database.
Aggiornamento del database
Prerequisiti
Per completare questa procedura, è necessario avere accesso a un server che esegue SQL Server e in cui sia possibile creare un database.
Creare il database School
È possibile creare il database School in qualsiasi server che esegue SQL Server a cui si ha accesso come amministratore oppure è possibile utilizzare LocalDB.
Per creare il database School
In Esplora server aprire il menu di scelta rapida del nodo Connessioni dati, quindi scegliere Aggiungi connessione.
Verrà visualizzata la finestra di dialogo Aggiungi connessione.
Nella casella Nome server specificare il nome di un'istanza di SQL Server a cui è possibile accedere come amministratore oppure specificare (localdb\v11.0) se non si ha accesso a un server.
SQL Server Express LocalDB fornisce un server di database semplice per lo sviluppo e il test nel proprio computer. Per ulteriori informazioni su LocalDB, vedere Procedura dettagliata: creazione di un file di database locale in Visual Studio.
Un nuovo nodo viene creato in Esplora server in Connessioni dati.
Aprire il menu di scelta rapida per il nuovo nodo di connessione, quindi scegliere Nuova query.
Aprire Creazione del database di esempio School nel sito Web Microsoft e quindi copiare e incollare lo script che crea il database Student nella finestra dell'editor.
Creare e configurare un progetto F#
In questo passaggio viene creato un progetto e viene impostato l'utilizzo di un provider di tipi.
Per creare e configurare un progetto F#
Chiudere il progetto precedente, creare un altro progetto e denominarlo SchoolEDM.
In Esplora soluzioni aprire il menu di scelta rapida Riferimenti, quindi scegliere Aggiungi riferimento.
Scegliere il nodo Framework, quindi nell'elenco Framework scegliere System.Data, System.Data.Entity e System.Data.Linq.
Scegliere il nodo Estensioni, aggiungere un riferimento all'assembly FSharp.Data.TypeProviders, quindi scegliere OK per chiudere la finestra di dialogo.
Aggiungere il codice seguente per definire un modulo interno e aprire gli spazi dei nomi appropriati. Il provider di tipi può inserire i tipi solo in uno spazio dei nomi privato o interno.
module internal SchoolEDM open System.Data.Linq open System.Data.Entity open Microsoft.FSharp.Data.TypeProviders
Per eseguire il codice in questa procedura dettagliata interattivamente come script anziché come programma compilato, aprire il menu di scelta rapida del nodo del progetto, scegliere Aggiungi nuovo elemento, aggiungere un file di script F# e quindi aggiungere il codice in ogni passaggio allo script. Per caricare i riferimenti agli assembly, aggiungere le righe seguenti.
#r "System.Data.Entity.dll" #r "FSharp.Data.TypeProviders.dll" #r "System.Data.Linq.dll"
Evidenziare ogni blocco di codice mentre lo si aggiunge e premere ALT+INVIO per eseguirlo in F# Interactive.
Configurare il provider di tipi e connettersi a Entity Data Model
In questo passaggio si installa un provider di tipi con una connessione dati e si ottiene un contesto dati che consente di utilizzare i dati.
Per configurare il provider di tipi e connettersi a Entity Data Model
Digitare il codice seguente per configurare il provider di tipi SqlEntityConnection che genera i tipi F# basati su Entity Data Model creato precedentemente. Anziché la stringa di connessione EDMX completa utilizzare solo la stringa di connessione SQL.
type private EntityConnection = SqlEntityConnection<ConnectionString="Server=SERVER\InstanceName;Initial Catalog=School;Integrated Security=SSPI;MultipleActiveResultSets=true", Pluralize = true> >
Questa azione installa un provider di tipi con la connessione al database creata precedentemente. La proprietà MultipleActiveResultSets è necessaria quando si utilizza ADO.NET Entity Framework poiché questa proprietà consente di eseguire più controlli in modo asincrono nel database in una connessione, cosa che può verificarsi frequentemente nel codice ADO.NET Entity Framework. Per ulteriori informazioni, vedere Utilizzo di MARS (Multiple Active Result Set).
Ottenere il contesto dei dati, un oggetto contenente le tabelle del database come proprietà e le stored procedure e le funzioni del database come metodi.
let context = EntityConnection.GetDataContext()
Esecuzione di query nel database
In questo passaggio si utilizzano le espressioni di query F# per eseguire varie query sul database.
Per eseguire una query sui dati
Digitare il codice seguente per analizzare i dati provenienti da Entity Data Model. Notare l'effetto Pluralize = true che modifica la tabella del database Course in Courses e la tabella Person in 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)
Aggiornamento del database
Per aggiornare il database, utilizzare le classi e i metodi di Entity Framework. È possibile utilizzare due tipi di contesti dei dati con il provider di tipi SQLEntityConnection. Innanzitutto, ServiceTypes.SimpleDataContextTypes.EntityContainer è il contesto dei dati semplificato, che include solo le proprietà specificate che rappresentano le tabelle e le colonne del database. In secondo luogo, il contesto dei dati completo è un'istanza della classe Entity Framework ObjectContext, che contiene il metodo AddObject per aggiungere righe al database. Entity Framework riconosce le tabelle e le relazioni tra di esse, pertanto rafforza la coerenza tra database.
Per aggiornare il database
Aggiungere il seguente codice al programma: In questo esempio aggiungere due oggetti con una relazione tra di essi e aggiungere un docente e l'assegnazione dell'ufficio. La tabella OfficeAssignments contiene la colonna InstructorID che fa riferimento alla colonna PersonID nella tabella 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")
Non viene apportata alcuna modifica al database finché non viene chiamato SaveChanges.
A questo punto ripristinare il database allo stato iniziale eliminando gli oggetti aggiunti.
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")
Avviso
Quando si utilizza un'espressione di query, è necessario ricordare che la query è soggetta alla valutazione differita.Pertanto, il database è ancora aperto per la lettura di tutte le valutazioni concatenate, come nei blocchi di espressione lambda dopo ogni espressione di query.Qualsiasi operazione di database che in modo esplicito o implicito utilizza una transazione deve avvenire dopo che le operazioni di lettura sono state completate.
Passaggi successivi
Esplorare altre opzioni di query esaminando gli operatori di query disponibili in Espressioni di query (F#)e rivedere ADO.NET Entity Framework per comprendere le funzionalità disponibili quando si utilizza il provider di tipi.
Vedere anche
Attività
Procedura dettagliata: generazione di tipi F# da un file di schema EDMX (F#)
Riferimenti
Provider di tipo SqlEntityConnection (F#)