2011-03-06 26 views
407

Tengo un problema con Entity Framework en Asp.net. Quiero obtener el valor Id cada vez que agregue un objeto a la base de datos. ¿Cómo puedo hacer esto?¿Cómo puedo obtener Id de entidad insertada en Entity framework?

+11

La respuesta de Ladislav Mrnka a continuación es la respuesta correcta, y debe aceptarse como tal. –

+1

El OP solo se publicó una vez con su cuenta de él/ella, esta pregunta es más específica. Esto le otorgó casi 2k de reputación (!), La respuesta no está marcada como aceptada porque la cuenta está abandonada desde ese día. – MurariAlex

Respuesta

8

El objeto que está guardando debe tener un Id correcto después de propagar los cambios en la base de datos.

+0

tenemos un error como "se produjo un error al actualizar las entradas. Vea la excepción interna para más detalles" – ahmet

+25

¿ha visto la excepción interna? ;-) – Snowbear

691

Es bastante fácil. Si está utilizando ID generados por DB (como IDENTITY en MS SQL), solo tiene que agregar entidad a ObjectSet y SaveChanges en ObjectContext relacionado. Id se llenará automáticamente para usted:

using (var context = new MyContext()) 
{ 
    context.MyEntities.AddObject(myNewObject); 
    context.SaveChanges(); 

    int id = myNewObject.Id; // Yes it's here 
} 

marco de la entidad por defecto sigue a cada INSERT con SELECT SCOPE_IDENTITY() cuando se utilizan generados automáticamente Id s.

+30

Así que estás haciendo una pregunta incorrecta. Si tiene un problema con la excepción, debe hacer una pregunta que muestre su excepción (y excepción interna) y el fragmento de código que causa ese error. –

+1

Asegúrese de que la Entidad que está agregando sea una Entidad válida, por ejemplo, cualquier cosa con una restricción de base de datos de "no nulo" debe llenarse, etc. – fran

+1

@LadislavMrnka: ¿Qué ocurre con las propiedades de navegación del objeto recién creado? No parece que se llenen automáticamente después de guardar los cambios. –

10

Por favor, consulte este enlace.

http://www.ladislavmrnka.com/2011/03/the-bug-in-storegeneratedpattern-fixed-in-vs-2010-sp1/

usted tiene que establecer la propiedad de StoreGeneratedPattern a la identidad y luego probar su propio código.

O también puede utilizarlo.

using (var context = new MyContext()) 
{ 
    context.MyEntities.AddObject(myNewObject); 
    context.SaveChanges(); 

    int id = myNewObject.Id; // Your Identity column ID 
} 
+0

Igual que la respuesta más votado. – Lewis86

18

Necesita volver a cargar la entidad después de guardar intercambios. Porque ha sido alterado por un activador de base de datos que no puede ser rastreado por EF. Por lo que necesitamos para recargar la entidad de nuevo desde el PP,

db.Entry(MyNewObject).GetDatabaseValues(); 

Entonces

int id = myNewObject.Id; 

mirada en respuesta @jayantha por debajo pregunta:

How can I get Id of inserted entity in Entity framework when using defaultValue?

+1

Hola, cuando me gusta esto, aparece el error de compilación que dice: no puedo resolver las propiedades, por ejemplo Id o Name, ¿me pueden ayudar, por favor? –

+0

@MortezaAzizi Parece ser un error de problema de propiedad no manejado o nulo, pero ¿puede explicar o escribir más fragmentos de código? – QMaster

1

me encuentro con una situación donde necesito insertar los datos en la base de datos & al mismo tiempo requieren la identificación primaria usando el marco de la entidad. Solución:

long id; 
IGenericQueryRepository<myentityclass, Entityname> InfoBase = null; 
try 
{ 
    InfoBase = new GenericQueryRepository<myentityclass, Entityname>(); 
    InfoBase.Add(generalinfo); 
    InfoBase.Context.SaveChanges(); 
    id = entityclassobj.ID; 
    return id; 
} 
4
Repository.addorupdate(entity, entity.id); 
Repository.savechanges(); 
Var id = entity.id; 

Esto funcionará.

+1

Repository no es responsable de guardar los cambios en la base de datos. Es un trabajo de UnitOfWork. – tchelidze

37

He estado usando Ladislav Mrnka's answer para recuperar Ids con éxito al usar Entity Framework, pero estoy publicando aquí porque lo había omitido (es decir, usándolo donde no era necesario) y pensé que publicaría mis conclusiones aquí en caso de que las personas estén buscando "resolver" el problema que tenía.

Considere un objeto de pedido que tenga una relación de clave externa con el cliente. Cuando agregué un nuevo cliente y un nuevo pedido al mismo tiempo, estaba haciendo algo como esto;

var customer = new Customer(); //no Id yet; 
var order = new Order(); //requires Customer.Id to link it to customer; 
context.Customers.Add(customer); 
context.SaveChanges();//this generates the Id for customer 
order.CustomerId = customer.Id;//finally I can set the Id 

Sin embargo, en mi caso esto no era necesario porque tenía una relación de clave externa entre customer.Id y el pedido.CustomerId

Todo lo que tenía que hacer era esto;

var customer = new Customer(); //no Id yet; 
var order = new Order{Customer = customer}; 
context.SaveChanges();//adds customer.Id to customer and the correct CustomerId to order 

Ahora cuando guardo los cambios, también se agrega al pedido el ID que se genera para el cliente. No necesito los pasos adicionales

Soy consciente de que esto no responde a la pregunta original, pero pensé que podría ayudar a los desarrolladores que son nuevos en EF a usar en exceso la respuesta más votado por algo que quizás no ser requerido.

+2

¡Gracias! IMPORTANTE Sugerencia para la mejor práctica: var order = new Order {Customer = customer}; Esto muestra el poder de Entity Framework para asignar objetos relacionados y el Id se actualizará automáticamente. –

+0

gracias por señalar específicamente esto. Estaba haciendo el predeterminado. + 1ed – user2695433

3

Puede obtener ID solo después de guardar, en su lugar puede crear un nuevo Guid y asignar antes de guardar.

0

Cuando se utiliza EF código 6.x primera

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid Id { get; set; } 

e inicializar una tabla de base de datos, se pondrá una

(newsequentialid()) 

dentro de las propiedades de la tabla bajo el encabezado predeterminado Valor o unión, lo que permite la ID que se debe llenar a medida que se inserta.

El problema es que si se crea una tabla y agregar la parte

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 

más tarde, los futuros update-bases de datos no van a volver a agregar el (newsequentialid())

Para fijar la forma correcta es para borrar la migración, eliminar la base de datos y volver a migrar ... o simplemente puede agregar (newsequentialid()) al diseñador de la tabla.

Cuestiones relacionadas