【问题标题】:Execute SQL command in Entity Framework Core 2.0 to delete all data in a table在 Entity Framework Core 2.0 中执行 SQL 命令删除表中的所有数据
【发布时间】:2018-02-17 06:37:14
【问题描述】:

我想从 Entity Framework Core 2.0 执行一条 SQL 命令,但我不知道该怎么做。

1.- 我需要这样做的原因是,我想从数据库表中删除所有数据,并且使用 Context.removeContext.removeRange 会产生对 DB 的多次调用(表中的每个数据一个) .

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>

【问题讨论】:

    标签: c# sql entity-framework-core asp.net-core-2.0


    【解决方案1】:

    确保您引用 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();
        }
    }
    

    【讨论】:

    • 那个参考是不够的。您还需要引用 Microsoft.EntityFrameworkCore.Relational,这是定义 ExecuteSqlCommand[Async] 的位置。
    • 在 EF Core 3.1 中,我们不应将 var connection = context.Database.GetDbConnection(); 包装在 using 块中。当你这样做时,上下文的连接被释放,然后尝试使用它会给出这个错误:The ConnectionString property has not been initialized..
    【解决方案2】:

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

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

    【讨论】:

    • ExecuteSqlRaw 似乎在 3.1 中不存在。
    • 您需要在 nuget 包中添加 Microsoft.EntityFrameworkCore.Relational 才能访问 ExecuteSqlRaw 命令。
    【解决方案3】:

    这将执行任何从表方法中删除每行的行。

    context.ExecuteStoreCommand("TRUNCATE TABLE [" + tableName + "]");
    

    TRUNCATE TABLE 类似于没有 WHERE 的 DELETE 语句 条款;然而,TRUNCATE TABLE 更快,使用更少的系统和 事务日志资源。

    ExecuteStoreCommand

    TRUNCATE TABLE

    【讨论】:

      【解决方案4】:

      Context.Database.ExecuteSqlCommandContext.Database.ExecuteSqlCommandAsyncMicrosoft.EntityFrameworkCore.Relational 命名空间中可用。确保你有它的参考。

      然后它将在您的班级中可用,您可以像下面这样调用它,

      Context.ExecuteSqlCommand("TRUNCATE TABLE YOURTABLENAME");
      

      【讨论】:

        【解决方案5】:

        @Nkosi 是正确的,但从 EF Core 3.x 开始,您应该像 @KevinDimey 所说的那样使用 ExecuteSqlRaw

        除了@KevinDimey 的答案之外,还有过时的消息:

        ExecuteSqlCommand:

        对于使用纯字符串执行 SQL 查询,请使用 改为执行SqlRaw。用于执行 SQL 查询,使用 插值字符串语法来创建参数,使用 改为执行SqlInterpolated。

        ExecuteSqlCommandAsync:

        对于使用纯字符串异步执行 SQL 查询,请使用 改为执行SqlRawAsync。用于 SQL 查询的异步执行 使用插值字符串语法创建参数,使用 改为执行SqlInterpolatedAsync。

        使用方法:

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

        【讨论】:

          【解决方案6】:

          你可以试试这个

           context.Patients.ToList().ForEach(v => v.ChangeTracker.State = ObjectState.Deleted);
           context.SaveChanges();
          

          【讨论】:

          • 不是我,但我认为这是因为您的解决方案会生成多个查询来删除所有数据,每个带有 ObjectState.Deleted 的实体一个。除此之外,您的答案回答了如何删除所有数据,而不是如何从 EF Core 执行 SQL 命令。
          • 我没有投反对票,是的,这会“起作用”。但我会根据经验告诉你,如果你有大量患者要删除,这可能需要很长时间才能执行。使用 sql 执行批量删除性能要好得多。
          猜你喜欢
          • 2018-08-13
          • 2016-12-05
          • 2018-09-22
          • 2018-07-13
          • 1970-01-01
          • 1970-01-01
          • 2020-11-27
          • 1970-01-01
          • 2018-08-09
          相关资源
          最近更新 更多