Tutorial: Obtener acceso a una base de datos SQL mediante proveedores de tipo y entidades (F#)
Este tutorial sobre F# 3.0 muestra cómo obtener acceso a los datos con tipo para una base de datos SQL basándose en el Entity Data Model de ADO.NET. En el tutorial se muestra cómo configurar el proveedor de tipo de F# SqlEntityConnection para usarlo con una base de datos SQL, cómo escribir consultas en los datos, cómo llamar a procedimientos almacenados en la base de datos y cómo usar algunos de los tipos y métodos de ADO.NET Entity Framework para actualizar la base de datos.
Este tutorial muestra las tareas siguientes, que se deben realizar en el orden presentado a continuación para finalizarlo correctamente:
Crear la base de datos School.
Crear y configurar un proyecto de F#.
Configurar el proveedor de tipo y conectarse al Entity Data Model.
Consultar la base de datos.
Actualizar la base de datos
Requisitos previos
Para completar estos pasos, se debe tener acceso a un servidor que ejecute SQL Server donde se pueda crear una base de datos.
Crear la base de datos School
Se puede crear la base de datos School en cualquier servidor que ejecute SQL Server en el que tenga acceso administrativo o se puede usar LocalDB.
Para crear la base de datos School
En el Explorador de servidores, abra el acceso directo al nodo Conexiones de datos y, después, elija Agregar conexión.
Aparecerá el cuadro de diálogo Agregar conexión.
En la casilla Nombre del servidor, especifique el nombre de una instancia de SQL Server a la que tenga acceso administrativo o bien especifique (localdb\v11.0) si no tiene acceso a un servidor.
LocalDB de SQL Server Express proporciona un servidor de bases de datos ligero para el desarrollo y las pruebas en el equipo. Para obtener más información sobre LocalDB, consulte Tutorial: Crear un archivo de base de datos local en Visual Studio.
Se crea un nuevo nodo en el Explorador de servidores bajo Conexiones de datos.
Abra el menú contextual del nuevo nodo de conexión y, a continuación, elija Nueva consulta.
Abra el tema para crear la base de datos de ejemplo School en el sitio web de Microsoft y, a continuación, copie y pegue el script de base de datos que crea la base de datos Student en la ventana del editor.
Crear y configurar un proyecto de F#
En este paso, se crea un proyecto y se configura para usar un proveedor de tipo.
Para crear y configurar un proyecto de F#
Cierre el proyecto anterior, cree otro proyecto y denomínelo SchoolEDM.
En el Explorador de soluciones, haga clic en el menú contextual Referencias y, a continuación, elija Agregar referencia.
Elija el nodo Framework y, a continuación, en la lista Framework, elija System.Data, System.Data.Entity y System.Data.Linq.
Elija el nodo Extensiones, agregue una referencia al ensamblado FSharp.Data.TypeProviders y haga clic en el botón ACEPTAR para descartar el cuadro de diálogo.
Agregue el código siguiente para definir un módulo interno y abrir los espacios de nombres adecuados. El proveedor de tipo solo puede insertar tipos en un espacio de nombres privado o interno.
module internal SchoolEDM open System.Data.Linq open System.Data.Entity open Microsoft.FSharp.Data.TypeProviders
Para ejecutar el código de este tutorial de forma interactiva como script en lugar de como programa compilado, abra el menú contextual del nodo del proyecto, elija Agregar nuevo elemento, agregue un archivo de script de F# y, después, agregue el código de cada paso al script. Para cargar las referencias de ensamblado, agregue las líneas siguientes.
#r "System.Data.Entity.dll" #r "FSharp.Data.TypeProviders.dll" #r "System.Data.Linq.dll"
Resalte cada bloque de código al agregarlo y presione las teclas Alt + Intro para ejecutarlo en F# interactivo.
Configurar el proveedor de tipo y conectarse al Entity Data Model
En este paso, se configura un proveedor de tipo con una conexión de datos y se obtiene un contexto de datos que permite trabajar con los datos.
Para configurar el proveedor de tipo y conectarse al Entity Data Model
Escriba el código siguiente para configurar el proveedor de tipo SqlEntityConnection que genera tipos de F# basados en el Entity Data Model creado previamente. En lugar de la cadena de conexión de EDMX completa, use solo la cadena de conexión de SQL.
type private EntityConnection = SqlEntityConnection<ConnectionString="Server=SERVER\InstanceName;Initial Catalog=School;Integrated Security=SSPI;MultipleActiveResultSets=true", Pluralize = true> >
Esta acción configura un proveedor de tipo con la conexión de base de datos que se ha creado anteriormente. La propiedad MultipleActiveResultSets es necesaria cuando se usa ADO.NET Entity Framework porque permite que varios comandos se ejecuten de forma asincrónica en la base de datos en una conexión, lo que puede producirse con frecuencia en el código de ADO.NET Entity Framework. Para obtener más información, vea el tema Utilizar conjuntos de resultados activos múltiples (MARS).
Obtenga el contexto de datos, que es un objeto que contiene las tablas de base de datos como propiedades y los procedimientos almacenados y funciones de base de datos como métodos.
let context = EntityConnection.GetDataContext()
Consultar la base de datos
En este paso, se usan las expresiones de consulta de F# para ejecutar varias consultas en la base de datos.
Para consultar los datos
Escriba el código siguiente para consultar los datos del Entity Data Model. Tenga en cuenta el efecto de Pluralize = true, que cambia Course a Courses y Person a People en la tabla de base de datos.
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)
Actualizar la base de datos
Para actualizar la base de datos, se usan las clases y los métodos de Entity Framework. Se pueden usar dos tipos de contexto de datos con el proveedor de tipo SQLEntityConnection. En primer lugar, ServiceTypes.SimpleDataContextTypes.EntityContainer es el contexto de datos simplificado, que incluye solamente las propiedades proporcionadas que representan tablas y columnas de bases de datos. En segundo lugar, el contexto de datos completo es una instancia de la clase ObjectContextde Entity Framework, que contiene el método AddObject para agregar filas a la base de datos. Entity Framework reconoce las tablas y las relaciones entre ellas, por lo que refuerza la coherencia de la base de datos.
Para actualizar la base de datos
Agregue el código siguiente al programa. En este ejemplo, se agregan dos objetos con una relación entre ellos y se agrega un instructor y una asignación de oficina. La tabla OfficeAssignments contiene la columna InstructorID, que hace referencia a la columna PersonID de la tabla 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")
Nada cambia en la base de datos hasta que se llame a SaveChanges.
Ahora, restaure la base de datos a su estado anterior eliminando los objetos que agregó.
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")
Advertencia
Cuando se usa una expresión de consulta, debe recordar que la consulta está sujeta a la evaluación diferida.Por tanto, la base de datos sigue abierta para lectura durante cualquier evaluación encadenada, por ejemplo en los bloques de expresiones lambda después de cada expresión de consulta.Cualquier operación de base de datos que use una transacción implícita o explícitamente debe aparecer después de que las operaciones de lectura se hayan completado.
Pasos siguientes
Explore otras opciones de consulta mediante la revisión de los operadores de consulta disponibles en Expresiones de consulta (F#) y revise también ADO.NET Entity Framework para entender la funcionalidad disponible al usar este proveedor de tipo.
Vea también
Tareas
Tutorial: Generar tipos en F# a partir de un archivo de esquema EDMX (F#)
Referencia
SqlEntityConnection (Proveedor de tipo de F#)