2011-03-08 12 views
11

Estoy usando el proveedor de Oracle para Entity framework (beta), y estoy enfrentando un problema.¿Cómo generar automáticamente identidad para una base de datos Oracle a través del marco Entity?

Nuestras tablas tienen columnas Id, que están configuradas para ser Identidad en StoreGeneratedPattern. Pensé que EF automáticamente haría "trabajos subyacentes", como crear secuencias y obtener una nueva identidad para cada registro que agregue a la tabla. Pero cuando corro código para agregar un nuevo registro, tales como:

var comment = new Comment 
{ 
    ComplaintId = _currentComplaintId, 
    Content = CommentContent.Text, 
    CreatedBy = CurrentUser.UserID, 
    CreatedDate = DateTime.Now 
}; 

context.Comments.AddObject(comment); 
context.SaveChanges(); 

una excepción todavía lanza, que es

{ "ORA-00001: restricción única (ADMINMGR.CONSTRAINT_COMMENT) violado" }

(CONSTRAINT_COMMENT es la restricción requiere que el comentario identidad debe ser único.

¿Cómo resuelvo esto?

¡Muchas gracias!

+0

http://stackoverflow.com/questions/8232997/generate-identity-for-an-oracle-database-through-entity-framework-using-an-exisi/19684494 # 19684494 –

Respuesta

15

StoreGeneratedPattern = "Identity" simplemente le dice a EF que el valor se generará al lado de la base de datos en la inserción, y que no debe proporcionar un valor en las instrucciones de inserción.

Todavía es necesario crear una secuencia de Oracle:

create sequence ComplaintIdSequence minvalue 1 maxvalue 9999999 start with 1 increment by 1;

y un disparador para hacer inserciones de mesa usan:

create or replace trigger CommplaintIdTrigger 
before insert on comment for each row 
begin 
    if :new.ComplaintId is null then select ComplaintIdSequence.nextval into :new.ComplaintId from dual; 
    endif; 
end;
+1

Gracias por su respuesta, pero aún no puedo creer que Oracle simplemente no haya hecho esto automáticamente :( – Vimvq1987

+0

Oracle debería absolutamente * no * hacer eso automáticamente. (Porque exactamente lo que * puede * hacer es más flexible de lo que piensas). Es trabajo de tu framework entender (y ocultar) las diferencias entre las plataformas de base de datos. –

+2

No dije que Oracle debería hacerlo en su base de datos, pero definitivamente debería hacerlo en su proveedor (el " marco "en su comentario) – Vimvq1987

0

Otra opción sería:

crear una secuencia la forma en que Alextansc describió. Cree un procedimiento almacenado que use MySequence.nextval como su clave principal.

¡Mapa 'inserte' para este modelo en su procedimiento almacenado y funciona!

He probado esto usando el primer enfoque de la base de datos.

El uso de la primera asignación de bases de datos a un procedimiento almacenado es bastante simple. Vaya a su archivo edmx y haga clic con el botón derecho en el modelo que desea asignar a un procedimiento almacenado. Haga clic en "asignaciones de procedimientos almacenados". El cuadro de diálogo en la parte inferior de la página le ofrece tres menús desplegables para la inserción, actualización y eliminación de mapas en los procedimientos almacenados.

0

Estoy usando Oracle ODP.NET, controlador administrado y Entity Framework 6. Creé mis tablas utilizando el enfoque de primer código pero no pude agregar ningún registro debido a una clave primaria nula.

La solución fue otorgar mi usuario tanto:
'CREATE SEQUENCE' y
'CREATE TRIGGER'
permisos y volver a crear el esquema.

Me di cuenta de esto después de usar la bandera -verbose en la consola de gestión de paquetes

0

En lugar de recordar todo esto SQL, fácilmente se podría hacer mediante el uso de Mig# así:

 var schema = new DbSchema(ConnectionString, DbPlatform.Oracle12c); 
     schema.Alter(db => db.CreateTable("TableName") 
      .WithPrimaryKeyColumn("Id", DbType.Int32).AsIdentity() 
      ...); 

En este ejemplo , la columna Id tendrá el desencadenador requerido y la secuencia generada por Mig # automáticamente.

+0

¿Alguien ha hecho esto? – Worthy7

0

Oracle 12c lo ha resuelto

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
public int SomeNumber { get; set; } 
Cuestiones relacionadas