【问题标题】:Pass Table Name as Parameter to Dapper将表名作为参数传递给 Dapper
【发布时间】:2014-07-29 14:20:43
【问题描述】:

是否可以将 表名 作为参数传递给 Dapper Query 命令?我不是在寻找 SQL 表定义的函数或 SQL 表变量。我想在 C# 中定义表名并将其传递给 Dapper。这是我的代码,执行时返回错误Must declare the table variable "@TableName"

var foo = conn.Query("SELECT * FROM @TableName WHERE Id = @Id", new { TableName = "MyTable", Id = 123 });

【问题讨论】:

    标签: dapper


    【解决方案1】:

    SQL 不支持参数化表名,而 dapper 是对 SQL 的非常薄的包装器 - 所以:不。

    但是,您可以使用 string.format:

    string sql = string.Format("... from [{0}] ...", table name);
    

    请注意,即使使用 [/],这也存在固有的 SQL 注入风险。

    【讨论】:

    • 谢谢马克。感谢您的输入,我目前正在按照您对 string.format 的建议进行操作。我也意识到注入风险,但这是针对由我们控制的内部脚本,不可能有未知的输入。
    • 从 c#6 开始,您可以使用字符串插值: $"select * from {tablename} where id = @Id" 然后对其他所有内容使用参数。但是没有解决 sql 注入风险。
    • 如果替换空格 ``string sql = string.Format("... from [{0}] ...", tableName.replace(" ",""));` ``不容易被sql注入吧?
    • @love2code 对 SQL 注入没有任何作用,并且对象/模式/等名称中允许有空格。
    • @MarcGravell 假设恶意用户试图注入此 sql 以删除输入中的员工表而不是真实数据表,例如:post; drop table employees; 没有空格的这将只是 post;droptableemployees;这不起作用,它会导致sql引擎运行出错。就我而言,我的数据表上没有空格,所以这就是我提到它的原因,因为它可能对我有用。
    【解决方案2】:

    您可以先检查表是否存在以防止 Sql 注入:

    string tableNameExistsCheck = "SELECT count(1) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @tableName";
    
    if (c.QuerySingle<int>(tableNameExistsCheck, new { tableName }) == 1)
    {
        string sql = string.Format("... from [{0}] ...", tableName);
        var result = c.Query(sql);                    
    }
    

    【讨论】:

    • 我真的很喜欢这种方法。运行起来有点开销,但是如果需要动态插入表名,这确实可以帮助缓解 SQL 注入
    【解决方案3】:

    对于内部的通用脚本,我们使用 TableNameMapper 来构建 sql:

    public async Task<bool> DeleteAsync(int id)
    {
        string tableName = Dapper.Contrib.Extensions.SqlMapperExtensions.TableNameMapper(typeof(T));
        using (var conn = new SqlConnection(ConnectionString))
        {
            int affectedRows = await conn.ExecuteAsync($"delete from {tableName} where id=@id", new { id });
            return affectedRows > 0;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多