SET IDENTITY_INSERT ON y LinqToSQL
Recientemente he tenido que realizar un pequeño programa para migrar datos. Leia de una base de datos y grababa en otra, ambas SQL Server 2000.
Me decidí a usar VS 2008 y LinqToSQL por la rapidez en el desarrollo. No podía usar Integration Services ni DTS (o al menos no me parecio practico), ya que entre otras cosas tenia que crear y tratar documentos.
El caso es que a la hora de realizar inserciones en la tabla de destino, la clave primaria estaba definida como identity - pero necesitaba insertar los mismos valores en ambas bases de datos - y me encontraba con el siguiente error.
Explicit value must be specified for identity column in table 'DatosIdentity' when IDENTITY_INSERT is set to ON.
La solucion es sencilla, pero seguro que a mas de uno le ahorro un dolor de cabeza. Sencillamente debemos habilitar la inserción en los campos de identidad a través de la instruccion SET IDENTITY_INSERT. Pero al estar utilizando Linq To SQL la cosa cambia entre SQL Server 2005 y SQL 2000. Mientras que SQL Server 2005 todo funciona bien a la primera, en SQL Server 2000 se produce el error anterior.
Vamos a crear un tabla con un campo identity y un proyecto con Visual Studio 2008 en el que grabamos datos en dicha tabla.
Primero creamos la tabla sobre SQL Server 2005.
CREATE TABLE DatosIdentity( Id int IDENTITY NOT NULL, Dato varchar(50) NULL, Fecha datetime NULL CONSTRAINT PK_DatosIdentity PRIMARY KEY (Id))
|
En nuestro proyecto de VS 2008 añadimos un formulario y modelo de datos de LinqToSQLClasses (ver como) conectado a SQL Server 2005.
En el formulario programos un botón de la siguiente manera:
using (DataClasses1DataContext ctx = new DataClasses1DataContext()) { ctx.ExecuteCommand( "SET IDENTITY_INSERT DatosIdentity ON"); DatosIdentity datos = new DatosIdentity(); datos.Id = 1; datos.Dato = "Devjoker.com"; datos.Fecha = DateTime.Now; ctx.DatosIdentities.InsertOnSubmit(datos); ctx.SubmitChanges(); ctx.ExecuteCommand( "SET IDENTITY_INSERT DatosIdentity OFF"); }
|
En SQL Server 2005 funcionara bien, pero si cambiamos la cadena de conexion y empezamos a trabajar con con SQL Server 2000 obtendremos el sguiente error:
Explicit value must be specified for identity column in table 'DatosIdentity' when IDENTITY_INSERT is set to ON.
La solucion es cambiar los decoradores de la propieda identity y cambiar el atributo IsDbGenerated=false.
[ Column(Storage="_Id", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=false)] public int Id { get { return this._Id; } set { if ((this._Id != value)) { this.OnIdChanging(value); this.SendPropertyChanging(); this._Id = value; this.SendPropertyChanged("Id"); this.OnIdChanged(); } } }
|
Con esto funcionará.
El porque no lo sé, cosas que tienen las nuevas tecnologías.
Saludos, DJK