Próbuję dowiedzieć się, czy możliwe jest wykonanie polecenia typu "wstaw do ... wybierz" z LINQ do SQL. Trochę LINQ do kodu SQL, który pozwoliłby mi wysłać jedno polecenie SQL do bazy danych, która wstawiłaby wiele wierszy do podanej tabeli.Wykonywanie INSERT INTO ... WYBIERZ z LINQ do SQL
Na przykład, jak sprawić, aby LINQ do SQL wysłał następującą instrukcję T-SQL do bazy danych SQL Server?
INSERT INTO Table1
SELECT Table2.column1 + 1 AS column1, Table2.column2 + 2 AS column2
WHERE Table2.column3 > 100
Mógłbym oczywiście to osiągnąć za pomocą funkcji DataContext.ExecuteCommand
ale to będzie realizowane natychmiast, bez skorzystania z automatycznej obsługi transakcji otrzymasz z DataContext.SubmitChanges
. Oprócz tego mam serię aktualizacji i chciałbym, aby wszystkie zostały wycofane w przypadku błędu.
Wszelkie pomysły?
UPDATE: Tutaj jest rzeczywisty kod:
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
}
)
);
Szybkie wyjaśnienie: Podmiot T_EDR_FILEBODies
mapuje do tabeli bazy danych, która w zasadzie przechowuje zawartość niektórych plików tekstowych importujemy. Jeden rekord odpowiada jednej linii w pliku tekstowym.
Próbuję utworzyć przefiltrowaną wersję zawartości pliku, kopiując rekordy z jednego pliku, nadając im nowy identyfikator pliku (ID_EDR=id_edr_filt
), ale odfiltrowując niektóre linie. Jednostki LINQ do SQL to bezpośrednie odwzorowania do tabel bazy danych. Do tej pory nie dodałem żadnego kodu do mojego datacontextu. Mają klucze podstawowe, inaczej nie byłbym w stanie wstawiać na nich wstawek (czytałem gdzieś, że byłbym w stanie pozbyć się tego wyjątku, gdybym pozbył się kluczy podstawowych, ale jak widzisz, to nie byłoby działa w moim przypadku).
Kiedy uruchomić go otrzymuję następujący wyjątek rzucony przez InsertAllOnSubmit
:
Explicit konstrukcja typu podmiotu T_EDR_FILEBODY 'w zapytaniu nie jest dozwolony.
Domyślam się, że rozumiem, że jednoznaczne skonstruowanie podmiotu w zapytaniu byłoby problematyczne. Jednostki zwracane przez zapytania mają śledzenie zmian, zmiany są tłumaczone na bazę danych po wywołaniu submarów. Ale jak można przetłumaczyć, w bazie danych, zmiany w jednostce utworzonej po stronie klienta? Ale czy to naprawdę oznacza, że nigdy nie możesz wykonać polecenia typu INSERT INTO ... SELECT, używając LINQ do SQL?
można zrobić „Korzystanie _tx jak Nowy TransactionScope()” i owinąć ExecuteCommand i cokolwiek innego w nim? – StingyJack
Cóż, myślę, że mogę, i mogę być po prostu wybredny, ale trudno mi zaakceptować, że po prostu nie możesz wstawić do ... select statement using linq. Byłby to ogromny handycap. –