cómo usar las vistas en el marco de la entidad Code First [cerrado]

87

¿Cómo puedo usar la vista de la base de datos en el código del marco de la entidad primero?

Sagar
fuente
2
Ninguna de las respuestas a continuación explica cómo crear una vista mediante migraciones de EF. Vea esta respuesta para una pregunta similar.
Rudey
Aquí hay un hilo con exactamente la misma pregunta. - stackoverflow.com/questions/13593845/…
Div Tiwari
Prueba mi solución . Se evita la generación de migración para las tablas marcados como vistas
kogoia

Respuestas:

95

Si, como yo, está interesado solo en mapear entidades provenientes de otra base de datos (un erp en mi caso) para relacionarlas con entidades específicas de su aplicación, entonces puede usar las vistas como usa una tabla (mapee la vista en de la misma manera!). Obviamente, si intenta actualizar esas entidades, obtendrá una excepción si la vista no es actualizable. El procedimiento es el mismo que en el caso de las entidades normales (basadas en una tabla):

  1. Cree una clase POCO para la vista; por ejemplo FooView
  2. Agregue la propiedad DbSet en la clase DbContext
  3. Use un archivo FooViewConfiguration para establecer un nombre diferente para la vista (usando ToTable ("Foo"); en el constructor) o para establecer propiedades particulares

    public class FooViewConfiguration : EntityTypeConfiguration<FooView>      
    {
        public FooViewConfiguration()
        {
            this.HasKey(t => t.Id);
            this.ToTable("myView");
        }
    }
    
  4. Agregue el archivo FooViewConfiguration al modelBuilder, por ejemplo, anulando el método OnModelCreating del contexto:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new FooViewConfiguration ());
    }
    
Daniele Armanasco
fuente
64
+1 por no asumir que "Code First" == generación automática de base de datos
onetwopunch
3
@DaveJellison, ¿le importaría detallar o proporcionar un enlace sobre cómo agregar una vista como parte de un IDatabaseInitializer?
Ralph Shillington
18
¿Soy solo yo o todo el mundo está obteniendo una tabla vacía creada por la migración? ¿Hay alguna forma de evitarlo?
Kremena Lalova
4
Solo asegurándome aquí, ¿esta solución requiere que creemos una Vista en la base de datos SQL de antemano externamente? ¿Es posible definir la vista en el código y hacer que se complete en la base de datos a través del comando Agregar-Migración / Actualizar-Base de datos?
frostshoxx
6
Unas pocas cosas. 1. Esta respuesta no menciona que debe crear la vista manualmente usando SQL, esto se puede hacer usando una migración. 2. No es necesario que configure el nombre de la vista si el nombre de la clase coincide con el nombre de la vista. 3. Puede usar DataAnnotations de esta manera:, [Table("myView")]esto es posiblemente más simple que usar la creación de un EntityTypeConfiguration.
Rudey
23

Esto puede ser una actualización, pero para usar vistas con EF Code primero, simplemente agregue [Table ("NameOfView")] a la parte superior de la clase y todo debería funcionar bien sin tener que pasar por todos los obstáculos por los que están pasando los demás. Además, deberá informar una de las columnas como una columna [clave]. Aquí está mi código de muestra a continuación para implementarlo.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace SomeProject.Data
{
    [Table("SomeView")]
    public class SomeView
    {
        [Key]
        public int NameID { get; set; }
        public string Name { get; set; }
    }
}

Y así es como se ve el contexto

using System.Data.Entity;

namespace SomeProject.Data
{
    public class DatabaseContext : DbContext
    {
        public DbSet<SomeView> SomeViews { get; set; }
    }
}
Al Katawazi
fuente
2
Esta es la misma que la respuesta aceptada, excepto que usa DataAnnotations mientras que la respuesta aceptada usa EF Fluid API.
Rudey
4
En realidad, no, no lo es. Intenté, sin éxito, la respuesta aceptada y no funcionó bien para mí. Pero luego estoy usando Migraciones, por lo que esto puede haber afectado las cosas. Descubrí que primero tenía que hacer mis migraciones, LUEGO agregar mi clase de vista ya que ya existía en la base de datos. Lo manejaríamos exactamente de la misma manera si ya tuviéramos tablas existentes en la base de datos. Dado que una vista es una "tabla virtual", la sintaxis de la tabla en Entity Framework todavía funciona.
Charles Owen
11

Si todo lo que desea es un montón de objetos desnormalizados, entonces podría crear una IQueryable<TDenormolized>propiedad pública de solo obtención en su DbContextclase.

En el get, devuelve un resultado de Linq para proyectar los valores desnormoalizados en sus objetos desnormalizados. Esto podría ser mejor que escribir una vista de base de datos porque está programando, no está limitado solo por usar selectdeclaraciones. También es seguro en tiempo de compilación.

Solo tenga cuidado de no activar enumeraciones como ToList()llamadas, que romperán la consulta diferida y puede terminar obteniendo un millón de registros de la base de datos y filtrarlos en su servidor de aplicaciones.

No sé si esta es la forma correcta, pero lo intenté y me funciona.

viejo
fuente
6
Una de las razones por las que me gustaría usar vistas es que el SQL generado por EF no siempre es 'bueno': tenemos algunas jerarquías de herencia en nuestro modelo (descubrí las trampas demasiado tarde ...) y el uso de vistas nos permite para crear manualmente el SQL. Solo un contrapunto de por qué sería preferible una vista
Carl
2
Otra razón para no hacer esto podría ser el uso de expresiones de tabla comunes recursivas, que no están disponibles en LINQ. Pero por lo demás, este es un buen consejo para escenarios más simples.
Tom Pažourek
1
Usar una propiedad en lugar de una vista no es una opción si desea aprovechar los beneficios de una vista indexada .
Rudey
"no está limitado por utilizar únicamente sentencias de selección". ¿Qué quiere decir con esto? Todo lo que pueda hacer con LINQ se puede hacer usando sentencias SELECT, no se puede decir lo mismo al revés.
Rudey
3

Sé que esta es una pregunta antigua y hay muchas respuestas aquí, pero me vi obligado a tener un problema cuando uso esta respuesta y se produjo un error cuando uso el comando update-database en la Consola del Administrador de paquetes:

Ya existe un objeto llamado '...' en la base de datos.

y utilizo estos pasos para resolver este problema:

  1. ejecute este comando en la consola del administrador de paquetes: Add-migration intial
  2. En la carpeta Migraciones, puede encontrar el archivo ..._ intial.cs, abrirlo y comentar o eliminar cualquier comando relacionado con su clase que desee asignar
  3. ahora normalmente puede usar el comando update-database para cualquier otro cambio en sus modelos

Espero eso ayude.

Sepehr Estaki
fuente
1
¡Gracias! ¡Esto realmente ayudó! Como extra, en lugar de simplemente eliminar el código generado con EF Migrations, puede agregar allí migrationBuilder.Sql("CREATE OR REPLACE VIEW ...); Para que los colegas también puedan usarlo para actualizar su base de datos.
Rich_Rich