Code First en una base de datos existente

Este tutorial paso a paso proporciona una introducción al desarrollo de Code First destinado a una base de datos existente. Code First permite definir el modelo mediante clases de C# o VB.Net. Opcionalmente, se puede realizar una configuración adicional mediante atributos en las clases y propiedades o mediante una API fluida.

Requisitos previos

Tendrá que tener Instalado Visual Studio 2012 o Visual Studio 2013 para completar este tutorial.

También necesitará la versión 6.1 (o posterior) de Entity Framework Tools para Visual Studio instalada. Consulte Obtener Entity Framework para obtener información sobre cómo instalar la versión más reciente de Entity Framework Tools.

1. Creación de una base de datos existente

Normalmente, cuando el destino es una base de datos existente, ya estará creada, pero para este tutorial necesitamos crear una base de datos a la cual acceder.

Vamos a generar la base de datos.

  • Abra Visual Studio.

  • Vista -> Explorador de servidores

  • Haga clic con el botón derecho en Conexiones de datos -> Agregar conexión...

  • Si no se ha conectado antes a una base de datos desde el Explorador de servidores, debe seleccionar Microsoft SQL Server como origen de datos

    Select Data Source

  • Conéctese a la instancia de LocalDB y escriba Blogging como nombre de la base de datos

    LocalDB Connection

  • Seleccione Aceptar y se le preguntará si desea crear una nueva base de datos. Seleccione

    Create Database Dialog

  • La nueva base de datos aparecerá ahora en el Explorador de servidores, haga clic con el botón derecho en ella y seleccione Nueva consulta.

  • Copie el siguiente SQL en la nueva consulta y haga clic con el botón derecho en la consulta y seleccione Ejecutar.

CREATE TABLE [dbo].[Blogs] (
    [BlogId] INT IDENTITY (1, 1) NOT NULL,
    [Name] NVARCHAR (200) NULL,
    [Url]  NVARCHAR (200) NULL,
    CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([BlogId] ASC)
);

CREATE TABLE [dbo].[Posts] (
    [PostId] INT IDENTITY (1, 1) NOT NULL,
    [Title] NVARCHAR (200) NULL,
    [Content] NTEXT NULL,
    [BlogId] INT NOT NULL,
    CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([PostId] ASC),
    CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blogs] ([BlogId]) ON DELETE CASCADE
);

INSERT INTO [dbo].[Blogs] ([Name],[Url])
VALUES ('The Visual Studio Blog', 'http://blogs.msdn.com/visualstudio/')

INSERT INTO [dbo].[Blogs] ([Name],[Url])
VALUES ('.NET Framework Blog', 'http://blogs.msdn.com/dotnet/')

2. Crear la aplicación

Para simplificar las cosas, crearemos una aplicación de consola básica que use Code First para acceder a los datos:

  • Abra Visual Studio.
  • Archivo - > Nuevo - > Proyecto
  • En el menú de la izquierda, seleccione Windows y Aplicación de consola
  • Escriba CodeFirstExistingDatabaseSample como nombre
  • Seleccione Aceptar.

 

3. Modelo de ingeniería inversa

Usaremos Entity Framework Tools para Visual Studio para ayudarnos a generar código inicial y asignarlo a la base de datos. Estas herramientas simplemente generan código que también puede escribir manualmente si lo prefiere.

  • Proyecto -> Agregar nuevo elemento...

  • Seleccione Datos en el menú de la izquierda y, a continuación, ADO.NET Entity Data Model

  • Escriba BloggingContext como nombre y haga clic en Aceptar

  • Se inicia el Asistente para Entity Data Model

  • Seleccione Code First en Base de datos y haga clic en Siguiente

    Wizard One CFE

  • Seleccione la conexión a la base de datos que creó en la primera sección y haga clic en Siguiente

    Wizard Two CFE

  • Haga clic en la casilla situada junto a Tablas para importar todas las tablas y luego, haga clic en Finalizar

    Wizard Three CFE

Una vez que el proceso de ingeniería inversa se completa, una serie de elementos se habrá agregado al proyecto. Veamos lo que se ha agregado.

Archivo de configuración

Se ha agregado un archivo App.config al proyecto, este archivo contiene la cadena de conexión a la base de datos existente.

<connectionStrings>
  <add  
    name="BloggingContext"  
    connectionString="data source=(localdb)\mssqllocaldb;initial catalog=Blogging;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"  
    providerName="System.Data.SqlClient" />
</connectionStrings>

También observará otras opciones de configuración en el archivo de configuración, estas son las opciones predeterminadas de EF que indican a Code First dónde crear bases de datos. Puesto que estamos asignando a una base de datos existente, esta configuración se omitirá en nuestra aplicación.

Contexto derivado

Se ha agregado una clase BloggingContext al proyecto. El contexto representa una sesión con la base de datos, lo que nos permite consultar y guardar datos. El contexto expone un DbSet<TEntity> para cada tipo de nuestro modelo. También observará que el constructor predeterminado llama a un constructor base mediante la sintaxis name=. Esto indica a Code First que la cadena de conexión que se va a usar para este contexto debe cargarse desde el archivo de configuración.

public partial class BloggingContext : DbContext
    {
        public BloggingContext()
            : base("name=BloggingContext")
        {
        }

        public virtual DbSet<Blog> Blogs { get; set; }
        public virtual DbSet<Post> Posts { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
    }

Siempre debe usar la sintaxis name= cuando use una cadena de conexión en el archivo de configuración. Esto garantiza que, si la cadena de conexión no está presente, Entity Framework iniciará en lugar de crear una nueva base de datos por convención.

Clases de modelo

Por último, también se ha agregado una clase Blog y Post al proyecto. Estas son las clases de dominio que componen nuestro modelo. Verá anotaciones de datos aplicadas a las clases para especificar la configuración en la que las convenciones de Code First no se alinearían con la estructura de la base de datos existente. Por ejemplo, verá la anotación StringLength en Blog.Name y Blog.Url, ya que tienen una longitud máxima de 200 en la base de datos (el valor predeterminado Code First es usar la longitud máxima admitida por el proveedor de base de datos: nvarchar(max) en SQL Server).

public partial class Blog
{
    public Blog()
    {
        Posts = new HashSet<Post>();
    }

    public int BlogId { get; set; }

    [StringLength(200)]
    public string Name { get; set; }

    [StringLength(200)]
    public string Url { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

4. Leer y escribir datos

Ahora que tenemos un modelo, es el momento de usarlo para acceder a algunos datos. Implemente el método Main en Program.cs como se muestra a continuación. Este código crea una nueva instancia de nuestro contexto y, a continuación, la usa para insertar un nuevo blog. A continuación, usa una consulta LINQ para recuperar todos los blogs de la base de datos ordenados alfabéticamente por Título.

class Program
{
    static void Main(string[] args)
    {
        using (var db = new BloggingContext())
        {
            // Create and save a new Blog
            Console.Write("Enter a name for a new Blog: ");
            var name = Console.ReadLine();

            var blog = new Blog { Name = name };
            db.Blogs.Add(blog);
            db.SaveChanges();

            // Display all Blogs from the database
            var query = from b in db.Blogs
                        orderby b.Name
                        select b;

            Console.WriteLine("All blogs in the database:");
            foreach (var item in query)
            {
                Console.WriteLine(item.Name);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

Ahora puede ejecutar la aplicación y probarla.

Enter a name for a new Blog: ADO.NET Blog
All blogs in the database:
.NET Framework Blog
ADO.NET Blog
The Visual Studio Blog
Press any key to exit...

 

¿Qué ocurre si cambia mi base de datos?

El asistente de Code First a la base de datos está diseñado para generar un conjunto de puntos de partida de clases que luego puede ajustar y modificar. Si el esquema de la base de datos cambia, puede editar manualmente las clases o realizar otra ingeniería inversa para sobrescribir las clases.

Uso de migraciones de Code First a una base de datos existente

Si desea usar migraciones de Code First con una base de datos existente, consulte Migraciones de Code First a una base de datos existente.

Resumen

En este tutorial hemos visto el desarrollo de Code First mediante una base de datos existente. Usamos Entity Framework Tools para Visual Studio para hacer ingeniería inversa a un conjunto de clases que se asignan a la base de datos y que se podrían usar para almacenar y recuperar datos.