我试图在SQL Server数据库的for-each循环中使用EF6从三个db表(一个父表和两个子表)中删除多个记录。虽然我能够通过EF默认db.SaveChanges()
方法完成它,但整个过程速度慢得令人无法接受。因此,我倾向于使用下面的方法在单个事务中对三个表执行ExecuteSqlCommand
:
foreach (var sm in MyCollection)
{
var query = "DELETE t1, t2, t3 FROM @table1 as t1 " +
"JOIN @table2 as t2 ON t2.ID = t1.ID " +
"JOIN @table3 as t3 ON t3.ID = t1.ID";
List<SqlParameter> parameterList = new List<SqlParameter>();
parameterList.Add(new SqlParameter("@table1", table1));
parameterList.Add(new SqlParameter("@table2", table2));
parameterList.Add(new SqlParameter("@table3", table3));
SqlParameter[] parameters = parameterList.ToArray();
// Execute the query against the context. Note that this bypasses SaveChanges() and executes immediately.
int result = db.Database.ExecuteSqlCommand(query, parameters);
}
当前的方法在&#39;附近投掷错误,&#39;。
我的问题是:这是做这笔交易的正确方法,还有其他关于如何加快整个过程的建议?
注意:此数据库未启用级联删除,我无权添加它。
答案 0 :(得分:2)
您可以一次只针对一个表发出一个Delete语句。
但是为了保持多个Deletes操作原子,你可以在一个事务中包装三个delete语句。
此外,您无法传递表名,因为您尝试将该变量视为文字字符串而不是对象名称。
我会按照以下方式执行此操作:
首先创建处理删除操作的过程
程序定义
CREATE PROCEDURE usp_Delete_Records
@Table SYSNAME,
@ID INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = N' DELETE FROM ' + QUOTENAME(@Table)
+ N' WHERE ID = @ID'
Exec sp_executesql @Sql
,N'@ID INT'
,@ID
END
处理多次删除
BEGIN TRANSACTION;
EXEC usp_Delete_Records @Table1 , @ID
EXEC usp_Delete_Records @Table2 , @ID
EXEC usp_Delete_Records @Table3 , @ID
COMMIT TRANSACTION;