Reputation: 1601
How can I truncate a certain table with C# code, not SQL query?
I want the equivalent of TRUNCATE TABLE <table_name>
So far I've tried this:
context.Products.RemoveRange(context.Products);
however, it doesnt do anything
Upvotes: 4
Views: 14245
Reputation: 406
I have done things as below, for EF Core 5.0.11 This is working for SQL Server, Oracle, PostgreSQL
public class AnnotationHelper
{
/*
* https://stackoverflow.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);
}
Upvotes: 5
Reputation: 529
re: extensions as mentioned by CodeCaster: If you are allowed to use NUGET packages in your code, you might find this library useful; it has 'Truncate' and 'TruncateAsync' exactly as you've asked about.
https://github.com/borisdj/EFCore.BulkExtensions
Yes, behind the scenes it is still using 'ExecuteSqlRaw', but using a c# method allows better error handling. For example, in some cases database security may not allow table truncation by the executing thread, so if that's important to your application you can handle it easier with a wrapper.
Upvotes: 1
Reputation: 151594
You can't, that's not what an ORM is for.
An ORM helps you access the database in terms of object access. Truncating a table is a data layer operation, not an object operation. The equivalent in Entity Framework would be to load all objects from the database and delete them one by one.
You don't want that, you want to truncate the table. Then dive down into SQL and truncate that table.
Surely there are extensions on Entity Framework that allow things like this, but in the end they will generate exactly the SQL you're preventing to execute, so why not simply do that yourself?
Upvotes: 8