实体框架核心中的截断表

cry*_*yxn 3 c# sql entity-framework entity-framework-core

如何使用 C# 代码而不是 SQL 查询截断某个表?

我想要相当于TRUNCATE TABLE <table_name>

到目前为止我已经尝试过这个:

context.Products.RemoveRange(context.Products);

然而,它没有做任何事情

Cod*_*ter 6

你不能,这不是 ORM 的用途。

ORM 帮助您以对象访问的方式访问数据库。截断表是数据层操作,而不是对象操作。实体框架中的等效操作是从数据库加载所有对象并一一删除它们。

您不希望这样,您想截断表。然后深入研究 SQL 并截断该表。

当然,实体框架上有一些扩展允许这样的事情,但最终它们将准确地生成您阻止执行的 SQL,那么为什么不自己简单地这样做呢?


Dip*_*Roy 5

我为 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)