c# - mvc - ¿Cómo puedo obtener la identificación de la entidad insertada en Entity framework?
entity framework database first español (11)
Tengo un problema con Entity Framework en Asp.net. Quiero obtener el valor de identificación cada vez que agrego un objeto a la base de datos. ¿Cómo puedo hacer esto?
Cuando usas el código EF 6.x primero
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
e inicializar una tabla de base de datos, pondrá una
(newsequentialid())
dentro de las propiedades de la tabla bajo el encabezado Valor predeterminado o Enlace, lo que permite que la ID se complete cuando se inserta.
El problema es si creas una tabla y agregas la
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
parte más adelante, las futuras bases de datos de actualización no volverán a agregar (newsequentialid ())
Para corregirlo, borre la migración, elimine la base de datos y vuelva a migrar ... o simplemente agregue (newsequentialid ()) al diseñador de tablas.
El objeto que está guardando debe tener una Id
correcta después de propagar los cambios en la base de datos.
Es bastante facil Si está utilizando Ids generados en base de datos (como IDENTITY
en MS SQL) solo necesita agregar una entidad a ObjectSet
y SaveChanges
en ObjectContext
relacionado. Id
se llenará automáticamente por ti:
using (var context = new MyContext())
{
context.MyEntities.AddObject(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Yes it''s here
}
Entity framework por defecto sigue a cada INSERT
con SELECT SCOPE_IDENTITY()
cuando se usan las Id
generadas automáticamente.
Había estado utilizando la respuesta de Ladislav Mrnka para recuperar con éxito los identificadores cuando utilizaba el Entity Framework. Sin embargo, estoy publicando aquí porque lo había estado utilizando incorrectamente (es decir, usándolo donde no era necesario) y pensé que publicaría mis hallazgos aquí. Por si la gente está 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 obligatorio porque tenía una relación de clave externa entre el cliente. Id y orden.
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, la identificación que se genera para el cliente también se agrega a la orden. No necesito los pasos adicionales.
Estoy 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 demasiado la respuesta más votada para algo que puede no ser necesario.
Hay dos estrategias:
Usar
ID
generado por la base de datos (int
oGUID
)Contras:
Debe realizar
SaveChanges()
para obtener elID
para entidades guardadas.Pros:
Puede usar
int
identidad.Use el
ID
generado por el cliente - solo GUID.Pros: Minificación de operaciones de
SaveChanges
. Capaz de insertar un gran gráfico de objetos nuevos por una operación.Contras:
Permitido solo para
GUID
Me encuentro con una situación en la que necesito insertar los datos en la base de datos y al mismo tiempo requerir la identificación primaria utilizando 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;
}
Necesitas recargar la entidad después de savechanges. Porque ha sido alterado por un disparador de base de datos que EF no puede rastrear. Así que necesitamos volver a cargar la entidad de nuevo desde la base de datos,
db.Entry(MyNewObject).GetDatabaseValues();
Entonces
int id = myNewObject.Id;
Mire la respuesta de @jayantha en la siguiente pregunta:
Ver la respuesta de @christian en la siguiente pregunta puede ayudar también:
Entity Framework ¿Actualizar contexto?
Por favor, consulte este enlace.
http://www.ladislavmrnka.com/2011/03/the-bug-in-storegeneratedpattern-fixed-in-vs-2010-sp1/
Debe establecer la propiedad de StoreGeneratedPattern en identidad y luego probar su propio código.
O también puedes usar esto.
using (var context = new MyContext())
{
context.MyEntities.AddObject(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Your Identity column ID
}
Puede obtener la ID solo después de guardar, en su lugar, puede crear un nuevo Guid y asignar antes de guardar.
Todas las respuestas son muy adecuadas para sus propios escenarios, lo que hice diferente es que asigné el int PK directamente desde el objeto (TEntity) que Add () devolvió a una variable int como esta;
using (Entities entities = new Entities())
{
int employeeId = entities.Employee.Add(new Employee
{
EmployeeName = employeeComplexModel.EmployeeName,
EmployeeCreatedDate = DateTime.Now,
EmployeeUpdatedDate = DateTime.Now,
EmployeeStatus = true
}).EmployeeId;
//...use id for other work
}
así que en lugar de crear un nuevo objeto completo, simplemente toma lo que quieras :)
EDITAR para el Sr. @GertArnold:
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;
Esto funcionará.