Estoy tratando de averiguar si es posible realizar un comando de tipo "insertar en ... seleccionar" con LINQ to SQL. Un poco de código LINQ a SQL que me permitiría enviar un único comando SQL a la base de datos que insertaría varias filas en una tabla determinada.Realización de un INSERT INTO ... SELECT con LINQ to SQL
Por ejemplo, ¿cómo hacer LINQ to SQL para enviar la siguiente instrucción T-SQL a una base de datos SQL Server?
INSERT INTO Table1
SELECT Table2.column1 + 1 AS column1, Table2.column2 + 2 AS column2
WHERE Table2.column3 > 100
que podría, por supuesto, lograr esto mediante el uso de la función DataContext.ExecuteCommand
pero esto sería ejecutado inmediatamente sin tomar ventaja de la operación automática de manipulación que se obtiene con DataContext.SubmitChanges
. Tengo una serie de actualizaciones además de ésta y me gustaría que todas sean resueltas en caso de error.
¿Alguna idea?
ACTUALIZACIÓN: Aquí está el código real:
var bs_prep =
from b in dc.T_EDR_FILEBODies
join
unpaid in dc.V_UNPAIDs
on
b.NUM_ADC.Substring(1, 9) equals unpaid.NOCONT
join
acordo in dc.T_ACORDOS_RECOM_APREs
on
Convert.ToInt32(b.NUM_ADC.Substring(1, 9)) equals acordo.ID_Contrato
where
b.ID_EDR == id_edr
&&
(
unpaid.NUM_INCUMPRIMENTOS <= max_unpaid_consec
&&
unpaid.TOTAL_NUM_INCUPRIMENTOS <= max_unpaid_nonconsec
)
||
(
acordo.Activo == true
&&
acordo.Data_Recomeco <= now
)
select new
{
ID_EDR = id_edr_filt,
NUM_LINHA = b.NUM_LINHA,
CODREJ = b.CODREJ,
HDT = b.HDT,
IMPORT = b.IMPORT,
NIB_DEV = b.NIB_DEV,
NUM_ADC = b.NUM_ADC,
REF_DD_BC = b.REF_DD_BC,
REF_MOV = b.REF_MOV
}
;
dc.T_EDR_FILEBODies.InsertAllOnSubmit(
bs_prep.Select(
b => new T_EDR_FILEBODY{
CODREJ = b.CODREJ,
HDT = b.HDT,
ID_EDR = b.ID_EDR,
IMPORT = b.IMPORT,
NIB_DEV = b.NIB_DEV,
NUM_ADC = b.NUM_ADC,
NUM_LINHA = b.NUM_LINHA,
REF_DD_BC = b.REF_DD_BC,
REF_MOV = b.REF_MOV
}
)
);
explicación rápida: La entidad T_EDR_FILEBODies
mapea a una tabla de base de datos que básicamente almacena el contenido de algunos archivos de texto que importamos. Un registro corresponde a una línea en el archivo de texto.
Lo que intento hacer es crear una versión filtrada del contenido del archivo copiando los registros de un archivo, dándoles un nuevo ID de archivo (ID_EDR=id_edr_filt
) pero filtrando algunas de las líneas. Las entidades LINQ to SQL son asignaciones directas a las tablas de la base de datos. No he agregado ningún código a mi datacontext hasta el momento. Tienen claves primarias, o de lo contrario no podría hacer inserciones en ellas (leí en algún lugar que podría deshacerme de esa excepción si me deshace de las claves principales, pero, como puedes ver, eso no trabajo en mi caso).
Cuando lo ejecuto me sale el siguiente excepción lanzada por InsertAllOnSubmit
:
construcción explícita del tipo de entidad 'T_EDR_FILEBODY' en la consulta no está permitido.
Supongo que entiendo que construir explícitamente una entidad dentro de una consulta sería problemático. Las entidades devueltas por consultas tienen un seguimiento de cambios, los cambios se traducen a la base de datos cuando se llama a submitchanges. Pero, ¿cómo podría traducir, en la base de datos, los cambios en una entidad creada en el lado del cliente? Pero, ¿esto realmente significa que no se puede realizar un comando INSERT INTO ... SELECT type utilizando LINQ to SQL?
¿Puede usted hacer un "Uso _tx como Nueva TransactionScope()" y envolver el ExecuteCommand y todo lo que en ella? – StingyJack
Bueno, supongo que puedo, y podría ser exigente, pero me resulta difícil aceptar que no puedas hacer una inserción en ... seleccionar instrucción usando linq. Sería un gran handycap. –