在Entity Framework Core 2.0中执行SQL命令以删除表中的所有数据

35
我想从Entity Framework Core 2.0执行一个SQL命令,但是我不知道如何做。
1.- 我需要这样做的原因是我想删除数据库表中的所有数据,使用Context.remove或Context.removeRange会对数据库产生很多调用(每个数据都要调用一次)。 2.- 我已经阅读到了有一种方法叫做.ExecuteSqlCommand可以实现这一点,但是在我的Context.Database中不存在(也许在Core 2.0中已经删除了?)。这是信息的来源:Dropping table In Entity Framework Core and UWP 所以,基本上我需要使用EF Core 2.0从代码中删除一个表,并且据我所知,我需要执行一个SQL命令来实现这一点。
谢谢。
这是我的.csproj文件,以防我错过了什么。
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" />    
  </ItemGroup>

  <ItemGroup>
    <!--<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" />    -->
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
  </ItemGroup>

</Project>
6个回答

39

请确保引用Microsoft.EntityFrameworkCore,以包含所有必要的扩展方法,从而允许您执行原始的 SQL 命令。

我从源代码库中找到了 ExecuteSqlCommand 和相关的扩展方法。

int count = await context.Database.ExecuteSqlCommandAsync("DELETE FROM [Blogs]");

找到一篇文章建议使用ADO.Net。

首先从上下文中获取连接,创建一个命令并执行它。

using (var connection = context.Database.GetDbConnection()) {
    await connection.OpenAsync();     
    using (var command = connection.CreateCommand()) {
        command.CommandText = "DELETE FROM [Blogs]";
        var result = await command.ExecuteNonQueryAsync();
    }
}

21
那个参考资料不够,你还需要引用Microsoft.EntityFrameworkCore.Relational,那里定义了ExecuteSqlCommand[Async] - MEMark
2
在 EF Core 3.1 中,我们不应该将 var connection = context.Database.GetDbConnection(); 包装在 using 块中。这样做会导致上下文的连接被释放,尝试在之后使用它将会出现此错误:The ConnectionString property has not been initialized. - Berend Engelbrecht

22

对于 EF Core 3.x,请使用此命名空间和此代码:

using Microsoft.EntityFrameworkCore; 
...
context.Database.ExecuteSqlRaw("TRUNCATE TABLE [TableName]");

在3.1中似乎不存在ExecuteSqlRaw。 - NotImplementedException
2
您需要添加NuGet软件包Microsoft.EntityFrameworkCore.Relational才能使用ExecuteSqlRaw命令。 - ChronoZZ

7
这将对任何表格逐行执行删除操作。
context.ExecuteStoreCommand("TRUNCATE TABLE [" + tableName + "]");

TRUNCATE TABLE与没有WHERE子句的DELETE语句类似;但是,TRUNCATE TABLE更快且使用更少的系统和事务日志资源。

ExecuteStoreCommand

TRUNCATE TABLE


5
@Nkosi说得对,但自EF Core 3.x以来,您应该像@KevinDimey所说的那样使用ExecuteSqlRaw
除了@KevinDimey的答案外,附加信息如下:
ExecuteSqlCommand:
用于使用纯字符串执行SQL查询,请改用ExecuteSqlRaw。用于使用插值字符串语法创建参数执行SQL查询,请改用ExecuteSqlInterpolated。
ExecuteSqlCommandAsync:
用于异步执行使用纯字符串的SQL查询,请改用ExecuteSqlRawAsync。用于异步执行使用插值字符串语法创建参数的SQL查询,请改用ExecuteSqlInterpolatedAsync。
要使用的方法:
context.Database.ExecuteSqlRaw("DELETE FROM [Blogs]");

await context.Database.ExecuteSqlRawAsync("DELETE FROM [Blogs]");

4

Context.Database.ExecuteSqlCommandContext.Database.ExecuteSqlCommandAsync 可以在 Microsoft.EntityFrameworkCore.Relational 命名空间中找到。请确保已经引用了该命名空间。

接下来,可以在您的类中使用以下方式调用它:

Context.ExecuteSqlCommand("TRUNCATE TABLE YOURTABLENAME");

-4
你可以试试这个。
 context.Patients.ToList().ForEach(v => v.ChangeTracker.State = ObjectState.Deleted);
 context.SaveChanges();

4
不是我做的,但我认为你的解决方案会生成多个查询来删除所有带有ObjectState.Deleted实体的数据,每个实体一个查询。除此之外,你的答案回答了如何删除所有数据,但没有说明如何从EF Core执行SQL命令。 - MorgoZ
2
我没有点踩,是的,这个方法“可行”。但是从我的经验来看,如果你要删除大量患者,使用这种方法执行会花费很长时间。使用 SQL 执行批量删除效果更好。 - cacodev
你需要删除".Tolist()",在删除之前你正在获取所有的病人。 - acandaldev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接