是否可以将表名作为参数传递给Dapper查询命令?我不想要一个SQL表定义函数或SQL表变量。我想在C#中定义表名并将其传递给Dapper。这是我的代码,当执行时,返回一个错误必须声明表变量"@TableName"
。
var foo = conn.Query("SELECT * FROM @TableName WHERE Id = @Id", new { TableName = "MyTable", Id = 123 });
是否可以将表名作为参数传递给Dapper查询命令?我不想要一个SQL表定义函数或SQL表变量。我想在C#中定义表名并将其传递给Dapper。这是我的代码,当执行时,返回一个错误必须声明表变量"@TableName"
。
var foo = conn.Query("SELECT * FROM @TableName WHERE Id = @Id", new { TableName = "MyTable", Id = 123 });
SQL不支持参数化表名,而Dapper只是SQL的一个非常轻量级的封装 - 因此:不行。
但您可以使用string.format:
string sql = string.Format("... from [{0}] ...", table name);
请注意,即使使用[/]符号,仍存在内在的SQL注入风险。
为了防止 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);
}
对于内部通用脚本,我们使用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;
}
}
如果您只是通过id查询表,则可以使用Dapper.Contrib包。
在类型上添加Table属性和Id列上的Key属性,然后在连接上使用Get(dynamic id)扩展方法。
这样,您就不需要编写动态查询。
[Table("cardtype-orders")]
public class CardTypeOrder
{
[Key]
public Guid Id { get; set; }
public string Description { get; set; }
}
public class CardTypeOrderRepository: GenericRepository<CardTypeOrder>
{
}
public abstract class GenericRepository<T>
{
public T Get(object id)
{
using (var connection = GetConnection())
{
return connection.Get<T>(id);
}
}
}
post; drop table employees;
没有空格的话就会变成post;droptableemployees;
这样是行不通的,因为会导致 SQL 引擎运行时出错。在我的情况下,我的数据表上没有空格,所以我提到了它,因为这对我可能有效。 - love2code