2012-03-15 43 views
5

Estoy tratando de trabajar con EF CodeFirst en Oracle con ODP.net. Esta es mi clase DbContext:¿Cómo se configura DbContext para que funcione con Oracle ODP.Net y EF CodeFirst?

public class MyCEContext : DbContext { 

    public DbSet<Person> Persons { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
     modelBuilder.Entity<Person>().ToTable("PERSONS","myce"); 

    } 

    public MyCEContext() : 
     base(new OracleConnection(
      "Data Source=cebd; User ID=myce; Password=****;"), true) {} 

} 

El problema es que cuando intento hacer algo como esto:

MyCEContext context = new MyCEContext(); 
Person p = context.Persons.Find(1); 

consigo este error interno:

{"ORA-00942: table or view does not exist"} 

Y existe la tabla.

¿Qué estoy haciendo mal?

Respuesta

6

Como escribió Nick en su respuesta, el problema está relacionado con las comillas y el caso de la consulta generada, pero no con los nombres de la tabla, pero con el nombre de esquema:

SELECT * 
FROM "myce"."PERSONS" "Extent1" 

Así que la solución es muy simple, simplemente a mayúsculas el identificador de usuario y el nombre de esquema:

modelBuilder.Entity<Person>().ToTable("PERSONS","MYCE"); 

en general, todos deben estar en mayúsculas: tablas, esquemas y nombres de campo. Pero es mejor anotar cada propiedad mapeada con el atributo de columna en lugar de mayúsculas el nombre de propiedad:

[Column("FIRST_NAME")] 
    public string FirstName { get; set; } 

Así, los nombres serán más fáciles de leer, tanto en la base de datos y las clases.

+0

Tengo tanto las clases como las propiedades con anotaciones de datos con mayúsculas Esquema/Nombre de columna, respectivamente, y todavía no funcionan. Sin embargo, usar DbSet.Find no funciona, DbSet.SingleOrDefault() hace –

+0

¿Podría poner algún código de sus clases o mapeos? – fcaldera

+0

parecía ser un error tipográfico en uno de los atributos de anotación de tabla, por lo que parece que DbSet.Find atraviesa todas las clases y asigna em a sus tablas mientras usa SingleOrDefault() solo asigna en tiempo de ejecución las tablas necesarias para esa consulta porque así es como noté el error tipográfico Estaba pensando que, dado que SingleOrDefault funcionaba, todos los nombres de las tablas estaban bien. En resumen, Find asigna tu conjunto completo de listas de objetos DbContext. –

3

Su problema es más probable porque EF pasa la consulta a Oracle entre comillas, lo que significa que el caso en sus tablas y sus campos debe coincidir con el de la base de datos.

Así que si usted tenía el siguiente:

select name from persons; 

El código EF probablemente se disparaba el siguiente SQL:

select "NAME" from "PERSONS"; 

Agregar a su función OnModelCreating:

modelBuilder.Conventions.Remove<ColumnTypeCasingConvention>(); 

... y construye tu objeto POCO con nombres de propiedad mayúsculas en lugar de la c Plaza bursátil norteamericana.

Si quiere ver el SQL, rompa el código y eche un vistazo al objeto DbContext.Persons. Debería ver el comando real SQL que utilizará para consultar toda la tabla (bastante grande)

Nota

Utilizamos Oracle EF Código primer lugar en producción. Aunque oficialmente no es compatible, parece que no falta nada en la última versión de ODAC que lo evitará.

+0

Hola Nick, gracias por tu respuesta. El problema estaba en el nombre del esquema. Tenía que estar en mayúsculas. Y estoy de acuerdo con tu nota. – fcaldera

1

Puede llamar a ToString en la consulta de linq que ejecuta contra su objeto dbcontext. Esto le mostrará el SQL que se está generando.Eso debería ayudar a encontrar el problema

mi problema era doble:

  1. Mis nombres de las tablas estaban siendo pluralizado
  2. Mis nombres de las tablas estaban siendo precedidos por "dbo".
0

Si no desea asignar cada columna de su aplicación como una solución para el problema de cotización mencionado por @fcaldera, puede usar el proveedor "Devart's dotConnect for Oracle".

Y justo el siguiente código se necesita:

Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig config = 
       Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance; 

      config.Workarounds.DisableQuoting = true; 

Ahora puede asignar una clase "MiObjeto" a un MyObject mesa sin problemas. Y es lo mismo para las columnas.

Nota: La versión NuGet de "dotConnect for Oracle" no es compatible con Entity Framework. Es necesario descargar la versión de prueba o profesional del sitio de Devart.

Cuestiones relacionadas