实体框架核心中的截断表
Posted
技术标签:
【中文标题】实体框架核心中的截断表【英文标题】:Truncate table in entity framework core 【发布时间】:2021-05-16 03:42:34 【问题描述】:如何使用 C# 代码而不是 SQL 查询截断某个表?
我想要相当于TRUNCATE TABLE <table_name>
到目前为止,我已经尝试过:
context.Products.RemoveRange(context.Products);
但是,它什么也没做
【问题讨论】:
EF 无法做到这一点。但是,您可以在上下文中使用 SQL 查询,例如context.Database.ExecuteSqlRaw("Truncate table <table_name>");
顺便说一句,RemoveRange
应该可以工作(但它不会截断表格,它会为每个匹配的行使用delete
),之后您是否使用了context.SaveChanges()
?
@Magnetron 你是对的......我完全忘记了保存更改。现在可以了!
【参考方案1】:
我为 EF Core 5.0.11 做了如下的事情 这适用于 SQL Server、Oracle、PostgreSQL
public class AnnotationHelper
/*
* https://***.com/questions/45667126/how-to-get-table-name-of-mapped-entity-in-entity-framework-core
*/
private static string GetName(IEntityType entityType, string defaultSchemaName = "dbo")
//var schemaName = entityType.GetSchema();
//var tableName = entityType.GetTableName();
var schema = entityType.FindAnnotation("Relational:Schema").Value;
string tableName = entityType.GetAnnotation("Relational:TableName").Value.ToString();
string schemaName = schema == null ? defaultSchemaName : schema.ToString();
string name = string.Format("[0].[1]", schemaName, tableName);
return name;
public static string TableName<T>(DbSet<T> dbSet) where T : class
var entityType = dbSet.EntityType;
return GetName(entityType);
public static class EfHelper
/*
* need to install Microsoft.EntityFrameworkCore.Relational
*/
public static string Truncate<T>(this DbSet<T> dbSet) where T : class
var context = dbSet.GetService<ICurrentDbContext>().Context;
string cmd = $"TRUNCATE TABLE AnnotationHelper.TableName(dbSet)";
using (var command = context.Database.GetDbConnection().CreateCommand())
if (command.Connection.State != ConnectionState.Open)
command.Connection.Open();
command.CommandText = cmd;
command.ExecuteNonQuery();
return cmd;
[Test]
public void Truncate()
Db.Users.Add(new User()
Name = "Name",
Email = "Email",
CreatedBy = "CreatedBy",
CreatedOn = DateTime.Now
);
Db.SaveChanges();
Assert.GreaterOrEqual(Db.Users.ToList().Count, 1);
/*Truncate table*/
Db.Users.Truncate();
Assert.AreEqual(0, Db.Users.ToList().Count);
【讨论】:
【参考方案2】:re: CodeCaster 提到的扩展:如果你被允许在你的代码中使用 NUGET 包,你可能会发现这个库很有用;与您所询问的完全一样,它具有“Truncate”和“TruncateAsync”。
https://github.com/borisdj/EFCore.BulkExtensions
是的,在幕后它仍在使用“ExecuteSqlRaw”,但使用 c# 方法可以更好地处理错误。例如,在某些情况下,数据库安全性可能不允许执行线程截断表,因此如果这对您的应用程序很重要,您可以使用包装器更轻松地处理它。
【讨论】:
那 nuget 付钱了吗?我们可以在不付费的情况下使用 truncate 吗?【参考方案3】:你不能,这不是 ORM 的用途。
ORM 可帮助您在对象访问方面访问数据库。截断表是数据层操作,而不是对象操作。 Entity Framework 中的等价物是从数据库中加载所有对象并一一删除。
您不希望这样,您想截断表格。然后深入研究 SQL 并截断该表。
当然,实体框架上的扩展允许这样的事情,但最终它们会生成您阻止执行的 SQL,那么为什么不简单地自己做呢?
【讨论】:
谢谢。只是想知道我是否错过了文档中的某些内容。然后我将使用 ExecuteSqlRaw 来满足这些需求。谢谢!以上是关于实体框架核心中的截断表的主要内容,如果未能解决你的问题,请参考以下文章