Todo lo que tiene que hacer es crear una nueva instancia de la clase y a continuación, llamar InsertOnSumbit() en la tabla:
var foo = new MyFoo { Name = "foo1" };
var dc = new MyDataContext();
dc.Foos.InsertOnSubmit(foo);
dc.SubmitChanges();
la otra cosa que hay que estar seguro es de cómo se está incrementando la columna ID. En general, siempre me aseguro de usar la configuración de IDENTIDAD (1,1) en mis columnas de ID. Esto se declara en la columna de identificación de su entidad LINQ, así:
[Column(AutoSync = AutoSync.OnInsert, IsPrimaryKey = true, IsDbGenerated = true)]
public Int32 Id { get; set; }
Para evitar duplicados, lo que realmente necesita es lo que llamamos en mi tienda de "añadir" funcionalidad. En mi humilde opinión, esto se logra más fácilmente con un procedimiento almacenado - incluso tenemos una plantilla que utilizamos para ello:
USE [<Database_Name, sysobject, Database_Name>]
GO
CREATE PROCEDURE [<Schema, sysobject, dbo>].[<Table_Name, sysobject, Table_Name>__append]
(
@id INT OUTPUT,
@<Key_Param, sysobject, Key_Param> <Key_Param_Type, sysobject, VARCHAR(50)>
)
AS
BEGIN
SELECT @id = [id] FROM [<Schema, sysobject, dbo>].[<Table_Name, sysobject, Table_Name>s] (NOLOCK) WHERE [<Key_Param, sysobject, Key_Param>] = @<Key_Param, sysobject, Key_Param>
IF @id IS NULL
BEGIN
INSERT INTO [<Schema, sysobject, dbo>].[<Table_Name, sysobject, Table_Name>s] ([<Key_Param, sysobject, Key_Param>])
OUTPUT INSERTED.[id] INTO @inserted_ids
VALUES (@<Key_Param, sysobject, Key_Param>)
SELECT TOP 1 @id = [id] FROM @inserted_ids;
END
ELSE
BEGIN
UPDATE [<Schema, sysobject, dbo>].[<Table_Name, sysobject, Table_Name>s]
SET
[<Key_Param, sysobject, Key_Param>] = @<Key_Param, sysobject, Key_Param>
WHERE [id] = @id
END
END
GO
Es posible hacerlo en LINQ sin embargo, sólo una consulta de una lista de identificadores existentes (o lo que sea la columna que está tecleando fuera de):
var dc = new MyDataContext();
var existingFoos = dc.Foos.ToList();
var newFoos = new List<Foo>();
foreach(var bar in whateverYoureIterating) {
// logic to add to newFoos
}
var foosToInsert = newFoos.Where(newFoo => !existingFoos.Any(existingFoo => newFoo.Id == existingFoo.Id));
dc.Foos.InsertAllOnSubmit(foosToInsert);
dc.SubmitChanges();
// use the next line if you plan on re-using existingFoos. If that's the case I'd wrap dc.SubmitChanges() in a try-catch as well.
existingFoos.AddRange(foosToInsert);
esperando su edición ... –
La solución LINQ parece bastante lenta. Preguntarle a una mesa gigante que cargar los contenidos en la memoria parece inviable para mí. Tal vez debería seguir con el enfoque SP. –
Eso es lo que pensé ... Sin embargo, podría acelerar la solución LINQ solo seleccionando las propiedades que realmente necesita ... por ejemplo, solo la columna ID. Además, si puede volver a utilizar la consulta "existente" para varias ejecuciones, también será de ayuda. –