cry*_*yxn 3 c# sql entity-framework entity-framework-core
如何使用 C# 代码而不是 SQL 查询截断某个表?
我想要相当于TRUNCATE TABLE <table_name>
到目前为止我已经尝试过这个:
context.Products.RemoveRange(context.Products);
然而,它没有做任何事情
你不能,这不是 ORM 的用途。
ORM 帮助您以对象访问的方式访问数据库。截断表是数据层操作,而不是对象操作。实体框架中的等效操作是从数据库加载所有对象并一一删除它们。
您不希望这样,您想截断表。然后深入研究 SQL 并截断该表。
当然,实体框架上有一些扩展允许这样的事情,但最终它们将准确地生成您阻止执行的 SQL,那么为什么不自己简单地这样做呢?
我为 EF Core 5.0.11 做了如下操作,这适用于 SQL Server、Oracle、PostgreSQL
public class AnnotationHelper
{
/*
* /sf/ask/3196698851/
*/
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);
}
Run Code Online (Sandbox Code Playgroud)