'FromSql' 操作的结果中不存在所需的列 'xxxID' - .Net Core EF
The required column 'xxxID' was not present in the results of a 'FromSql' operation - .Net Core EF
我正在尝试为 .NET Core EF (3.1.9) 中的批量删除找到更好且性能更高效的方法。 (一次性删除大约 50 万到 100 万条记录。)
型号:
public class Employee
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int EmpID { get; set; }
public string EmpName { get; set; }
}
和数据库table为:
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: The required column 'EmpID' was not present in the results of a 'FromSql' operation.
ASP.NET 核心 EF 生成查询:
DELETE FROM [dbo].[Employee]
fail: Microsoft.EntityFramework.Query[10100] .... stack trace with above error.
已经调查过:
所以不确定为什么会抛出上述错误。因为数据库有正确的 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 中执行批量删除的更好方法是什么?
- 看起来 FromSqlRaw() 与“SELECT..”查询一起工作。
- 对于批量删除,我评估了以下方法,它比 dbContext.RemoveRange(entities) 更好;因为 RemoveRange() 为每个实体生成了单独的查询。然后每次查询都需要一些时间,所以不适合批量删除。相比之下,ExecuteSqlRaw(使用 where 条件)仅生成单个查询,对于 200K 条记录几乎不需要 250 毫秒。在高端服务器上,它肯定会更少。
public int Delete<TEntity>(string whereCondition, params object[] parameters) where TEntity: class
{
return DbContext.Database.ExecuteSqlRaw($"Delete from dbo.Employee WHERE {whereCondition}", parameters);
}
我正在尝试为 .NET Core EF (3.1.9) 中的批量删除找到更好且性能更高效的方法。 (一次性删除大约 50 万到 100 万条记录。)
型号:
public class Employee
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int EmpID { get; set; }
public string EmpName { get; set; }
}
和数据库table为:
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: The required column 'EmpID' was not present in the results of a 'FromSql' operation.
ASP.NET 核心 EF 生成查询:
DELETE FROM [dbo].[Employee]
fail: Microsoft.EntityFramework.Query[10100] .... stack trace with above error.
已经调查过:
所以不确定为什么会抛出上述错误。因为数据库有正确的 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 中执行批量删除的更好方法是什么?
- 看起来 FromSqlRaw() 与“SELECT..”查询一起工作。
- 对于批量删除,我评估了以下方法,它比 dbContext.RemoveRange(entities) 更好;因为 RemoveRange() 为每个实体生成了单独的查询。然后每次查询都需要一些时间,所以不适合批量删除。相比之下,ExecuteSqlRaw(使用 where 条件)仅生成单个查询,对于 200K 条记录几乎不需要 250 毫秒。在高端服务器上,它肯定会更少。
public int Delete<TEntity>(string whereCondition, params object[] parameters) where TEntity: class
{
return DbContext.Database.ExecuteSqlRaw($"Delete from dbo.Employee WHERE {whereCondition}", parameters);
}