【发布时间】:2021-04-08 00:39:54
【问题描述】:
我正在尝试在 .NET Core EF (3.1.9) 中找到更好且性能高效的批量删除方法。 (一次删除大约 500K 到 100 万条记录。)
型号:
public class Employee
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int EmpID { get; set; }
public string EmpName { get; set; }
}
而数据库表为:
CREATE TABLE [dbo].[Employee]
(
[EmpID] [int] IDENTITY(1,1) NOT NULL,
[EmpName] [nchar] (20) NULL,
CONSTRAINT [PK_dbo].[Employee]
PRIMARY KEY CLUSTERED ([EmpID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
尝试使用通用方法 1 删除记录。
public int Delete<TEntity>(Func<TEntity, bool> predicate) where TEntity: class
{
return DbContext.Set<TEntity>
.FromSqlRaw($"Delete from dbo.Employee")
.Where(predicate).Count();
}
并将此方法称为
Func<Employee, bool> myPredicate = x => x.EmpID > 10;
int deletedCount = myclass.Delete(myPredicate);
抛出异常:
InvalidOperationException:“FromSql”操作的结果中不存在所需的列“EmpID”。
ASP.NET Core EF 生成查询:
DELETE FROM [dbo].[Employee]
失败:Microsoft.EntityFramework.Query[10100] .... 出现上述错误的堆栈跟踪。
已经调查过了:
.NET Core Entity Framework InvalidOperationException
The required column 'CustomerId' was not present in the results of a 'FromSql' operation
The required column 'id' was not present in the results of a `FromSql` operation in EFcore
所以不知道为什么它会抛出错误。由于数据库具有正确的 PK 并且模型也具有它。也尝试了其他一些实体,它总是抛出与列名“xxxEntityColID”相同的错误。
但是,如果我使用以下代码,那么它可以工作:
public int Delete<TEntity>(string whereCondition, params object[] parameters) where TEntity: class
{
return DbContext.Database.ExecuteSqlRaw($"Delete from dbo.Employee WHERE {whereCondition}", parameters);
}
// and calling like
string myCondition = "EmpID > 10";
int deletedCount = myclass.Delete<Employee>(myCondition, new object[0]);
.NET Core EF 生成以下 SQL 并且可以正常工作。
DELETE FROM [dbo].[Employee] WHERE EmpID > 10;
问题
- 为什么会出现这个“xxxEntityColID”错误?
- 在 .NET Core EF 中进行批量删除的更好方法是什么?
【问题讨论】:
-
仅供参考:我已经尝试过 dbContext.RemoveRange(entities),它可以工作,但是它会为每个实体生成单独的查询。所以我认为这将是性能开销。