Tôi đang cố gắng tìm hiểu xem có thể thực hiện lệnh nhập "chèn vào ... chọn" với LINQ to SQL hay không. Một chút mã LINQ to SQL sẽ cho phép tôi gửi một lệnh SQL duy nhất tới cơ sở dữ liệu có thể chèn nhiều hàng vào một bảng đã cho.Thực hiện lệnh INSERT INTO ... SELECT với LINQ to SQL
Ví dụ, làm thế nào để làm cho LINQ to SQL gửi câu lệnh T-SQL sau đến cơ sở dữ liệu SQL Server?
INSERT INTO Table1
SELECT Table2.column1 + 1 AS column1, Table2.column2 + 2 AS column2
WHERE Table2.column3 > 100
tôi có thể đương nhiên đạt được điều này bằng cách sử dụng các chức năng DataContext.ExecuteCommand
nhưng điều này sẽ được thực thi ngay lập tức mà không cần dùng lợi thế của giao dịch tự động xử lý bạn nhận được với DataContext.SubmitChanges
. Tôi có một loạt các cập nhật bên cạnh điều này và tôi muốn tất cả chúng được khôi phục trong trường hợp có lỗi.
Bất kỳ ý tưởng nào?
UPDATE: Đây là mã thực tế:
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
}
)
);
Giải thích nhanh: Thực thể T_EDR_FILEBODies
bản đồ vào một bảng cơ sở dữ liệu mà cơ bản lưu trữ các nội dung của một số tập tin văn bản chúng tôi nhập khẩu. Một bản ghi tương ứng với một dòng trong tệp văn bản.
Điều tôi đang cố gắng tạo phiên bản đã lọc của nội dung tệp bằng cách sao chép các bản ghi từ một tệp, cung cấp cho họ ID tệp mới (ID_EDR=id_edr_filt
) nhưng lọc ra một số dòng. Các thực thể LINQ to SQL là ánh xạ trực tiếp tới các bảng cơ sở dữ liệu. Tôi đã không thêm mã vào datacontext của tôi cho đến nay. Họ có chìa khóa chính, hoặc nếu không tôi sẽ không thể chèn vào chúng (tôi đọc ở đâu đó tôi có thể loại bỏ ngoại lệ đó nếu tôi loại bỏ các khóa chính nhưng, như bạn thấy, điều đó sẽ không làm việc trong trường hợp của tôi).
Khi tôi chạy nó tôi nhận được ngoại lệ sau đây ném bởi InsertAllOnSubmit
:
xây dựng Explicit của loại thực thể 'T_EDR_FILEBODY' trong truy vấn không được phép.
Tôi đoán tôi hiểu rằng việc xây dựng một thực thể rõ ràng bên trong truy vấn sẽ có vấn đề. Các thực thể được truy vấn trả về có thay đổi theo dõi, các thay đổi được dịch sang cơ sở dữ liệu khi các cuộc gọi con được gọi. Nhưng làm thế nào bạn có thể dịch, vào cơ sở dữ liệu, thay đổi về một thực thể được tạo ra ở phía khách hàng? Nhưng điều này thực sự có nghĩa là bạn không bao giờ có thể thực hiện lệnh INSERT INTO ... SELECT bằng cách sử dụng LINQ to SQL?
Bạn có thể làm một "Sử dụng _tx như New TransactionScope()" và quấn ExecuteCommand và bất cứ điều gì khác trong nó? – StingyJack
Vâng tôi đoán tôi có thể, và tôi có thể chỉ là cầu kỳ nhưng tôi cảm thấy khó chấp nhận rằng bạn chỉ không thể làm một chèn vào ... chọn tuyên bố bằng cách sử dụng LINQ. Nó sẽ là một chiếc vòng tay rất lớn. –