Entity Framework Tutorial Inserción de identidad
En Entity Framework, cuando tiene un campo de clave principal como Id
o AuthorId
que se asigna a la columna IDENTITY
en la base de datos, funciona bien cuando inserta datos.
- En algunos casos, es posible que deba insertar valores explícitos en una columna
IDENTITY
SQL Server. - Para hacerlo, debes habilitar
IDENTITY_INSERT
antes de llamar aSaveChanges()
manualmente.
Digamos que queremos crear un nuevo autor con un valor AuthorId
explícito.
Author author = new Author() { AuthorId = 1001, Name = "Johny", Books = new List<Book> { new Book() { Title = "Learn VB.NET"}, new Book() { Title = "C# Fundamentals for Absolute Beginners"}, } };
Pero no puede insertar un autor con un valor de AuthorId
Autor explícito directamente en la columna de identidad, por lo que deberá activar IDENTITY_INSERT
antes de llamar a SaveChanges()
.
using (var context = new BookStore()) { Author author = new Author() { AuthorId = 1001, Name = "Johny", Books = new List<Book> { new Book() { Title = "Learn VB.NET"}, new Book() { Title = "C# Fundamentals for Absolute Beginners"}, } }; context.Authors.Add(author); context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [dbo].[Authors] ON"); context.SaveChanges(); context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [dbo].[Authors] OFF"); }
Desafortunadamente, cuando se llama a SaveChanges
el valor de identidad explícito se ignora y se usa un nuevo valor generado por la base de datos.
La solución es crear una nueva clase de contexto que heredará nuestra clase de contexto principal y anulará OnModelCreating
.
public class TempBookStore : BookStore { protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Author>() .Property(a => a.AuthorId) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); base.OnModelCreating(modelBuilder); } }
En la función OnModelCreating
podemos establecer el atributo en la entidad para que no genere valores automáticos para AuthorId
. También deberá asegurarse de envolver el comando SQL y la fila en una transacción.
using (var context = new TempBookStore()) { using (var transaction = context.Database.BeginTransaction()) { Author author = new Author() { AuthorId = 1001, Name = "Johny", Books = new List<Book> { new Book() { Title = "Learn VB.NET"}, new Book() { Title = "C# Fundamentals for Absolute Beginners"}, } }; context.Authors.Add(author); context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [dbo].[Authors] ON"); context.SaveChanges(); context.Database.ExecuteSqlCommand(@"SET IDENTITY_INSERT [dbo].[Authors] OFF"); transaction.Commit(); } }