You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在EntityFramework 6中编写原生SQL命令?含IN子句删除场景

解决方案

一、参数化原生SQL写法(规避注入+正确处理整数)

你当前的代码存在两个问题:一是WHERE关键字后缺少要匹配的列名(比如Id),二是直接拼接字符串存在SQL注入风险。通过参数化查询可以同时解决这两个问题,确保整数类型正确传递:

public void DeleteRow(List<int> rowIds)
{
    if (!rowIds.Any()) return; // 空列表直接返回,避免无效操作

    using (var db = new SkataModel())
    {
        // 生成带索引的参数,如@p0、@p1
        var parameters = rowIds.Select((id, index) => new SqlParameter($"@p{index}", id)).ToArray();
        // 拼接参数占位符
        var placeholders = string.Join(", ", parameters.Select(p => p.ParameterName));
        // 构造参数化SQL语句
        var sql = $"DELETE FROM db.T0590_CODE_STRING WHERE Id IN ({placeholders})";
        
        // EF6使用ExecuteSqlCommand,EF Core替换为ExecuteSqlRaw
        db.Database.ExecuteSqlCommand(sql, parameters);
    }
}

这种方式既保证了参数以整数类型传入数据库,又彻底消除了SQL注入风险,比直接字符串拼接更安全可靠。

二、Linq原生写法(简洁易维护)

如果不需要手写原生SQL,直接使用EF的Linq方法更高效:

方法1:先查询再删除(适用于数据量较小的场景)

public void DeleteRow(List<int> rowIds)
{
    if (!rowIds.Any()) return;

    using (var db = new SkataModel())
    {
        var targetEntities = db.T0590_CODE_STRING.Where(x => rowIds.Contains(x.Id));
        db.T0590_CODE_STRING.RemoveRange(targetEntities);
        db.SaveChanges();
    }
}

方法2:直接执行删除(EF Core 7+支持,无需查询实体)

如果数据量较大,不想先加载实体到内存,可以用ExecuteDelete直接在数据库执行删除:

public void DeleteRow(List<int> rowIds)
{
    if (!rowIds.Any()) return;

    using (var db = new SkataModel())
    {
        db.T0590_CODE_STRING.Where(x => rowIds.Contains(x.Id)).ExecuteDelete();
        // 无需调用SaveChanges,ExecuteDelete直接操作数据库
    }
}

三、关于你原写法的补充说明

你之前用string.Join拼接的方式,最终生成的SQL里虽然是数字格式(int转字符串后为"1,2,3",SQL会自动识别为整数),但这种写法存在严重的SQL注入风险,如果rowIds被恶意篡改,可能导致数据库被攻击,因此强烈不建议使用。参数化查询或Linq方法才是合规的解决方案。

内容的提问来源于stack exchange,提问作者Bouyalife

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:17:12