Я пытаюсь выяснить, возможно ли выполнить команду типа «insert into ... select» с LINQ to SQL. Немного кода LINQ to SQL, который позволит мне отправить одну SQL-команду в базу данных, которая будет вставлять несколько строк в заданную таблицу.Выполнение INSERT INTO ... SELECT с LINQ to SQL
Например, как заставить LINQ to SQL отправить следующую инструкцию T-SQL в базу данных SQL Server?
INSERT INTO Table1
SELECT Table2.column1 + 1 AS column1, Table2.column2 + 2 AS column2
WHERE Table2.column3 > 100
Я мог бы, конечно, добиться этого с помощью функции DataContext.ExecuteCommand
, но это будет выполняться сразу же без воспользовавшись автоматической операции обработки вы получаете с DataContext.SubmitChanges
. У меня есть ряд обновлений, кроме этого, и я бы хотел, чтобы все они откатились в случае ошибки.
Любые идеи?
UPDATE: Вот реальный код:
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
}
)
);
Краткое объяснение: T_EDR_FILEBODies
объект отображает таблицу базы данных, которые в основном хранит содержимое некоторых текстовых файлов, которые мы импортируем. Одна запись соответствует одной строке в текстовом файле.
Что я пытаюсь сделать, это создать отфильтрованную версию содержимого файла, скопировав записи из одного файла, предоставив им новый идентификатор файла (ID_EDR=id_edr_filt
), но отфильтровывая некоторые из строк. Объекты LINQ to SQL являются прямыми сопоставлениями таблиц базы данных. До сих пор я не добавил код в свой файл данных. У них есть первичные ключи, иначе я бы не смог сделать вставки на них (я где-то читал, что смог бы избавиться от этого исключения, если бы избавился от первичных ключей, но, как вы можете видеть, это не будет работа в моем случае).
Когда я запускаю его я получаю следующее исключение брошенного InsertAllOnSubmit
:
Явного строительства типа объекта «T_EDR_FILEBODY» в запросе не допускаются.
Я думаю, я понимаю, что явное конструирование объекта внутри запроса было бы проблематичным. Объекты, возвращаемые запросами, имеют отслеживание изменений, изменения переводятся в базу данных при вызове подписок. Но как вы могли бы перевести в базу данных изменения на сущности, созданной на стороне клиента? Но действительно ли это означает, что вы никогда не сможете выполнять команду INSERT INTO ... SELECT с использованием LINQ to SQL?
Вы можете сделать «Использование _tx в Нью-TransactionScope()» и оберните ExecuteCommand и все остальное в нем? – StingyJack
Ну, я думаю, я могу, и я могу просто быть разборчивым, но мне трудно принять, что вы просто не можете вставлять в ... select заявление с помощью linq. Это был бы такой огромный handycap. – 2010-03-02 17:49:19