使用Dapper的动态参数化查询

4
我希望能够编写一个具有动态参数列表的查询(取决于是否设置了参数)。 我想在使用dapper的oracle数据库上执行查询。
示例代码:
        var sqlParams = new List<object>();
        var sqlBuilder = new StringBuilder();
        sqlBuilder.Append("SELECT * FROM EXAMPLE WHERE 1 = 1 ");

        if (!string.IsNullOrEmpty(aParam))
        {
            sqlBuilder.Append(" AND A LIKE ?");
        }

        if (!string.IsNullOrEmpty(bParam))
        {
            sqlBuilder.Append(" AND B LIKE ? ");
        }

        var sql = sqlBuilder.ToString();

        return this.Connection.Query<Equipment>(
            sql,
            new { aParam, bParam }   // ??
            ).ToList();
1个回答

2

Dapper只能使用命名参数。我记得在Oracle中,它们是以冒号为前缀的,所以:

if (!string.IsNullOrEmpty(aParam))
{
    sqlBuilder.Append(" AND A LIKE :aParam");
}

if (!string.IsNullOrEmpty(bParam))
{
    sqlBuilder.Append(" AND B LIKE :bParam");
}

现在你的现有代码如下:
return this.Connection.Query<Equipment>(
    sql,
    new { aParam, bParam }
    ).ToList();

应该可以使用。Dapper使用匿名类型成员的名称作为参数名称。它还包括一些非常基本的代码来检查是否存在于sql中的任何成员,因此,如果您的sql只提到: bParam,它实际上不会将aParam值添加为参数。

在更复杂的情况下,还有一个DynamicParameters对象可以使用,它的功能更像是一个字典-但是在这里您不需要使用它。


你如何在第二个代码片段中动态添加 aParam, bParam?能否用 ExpandoObject 替换 new { aParam, bParam }?我不想硬编码 aParam, bParam。我想通过循环来添加它们。但似乎 Query<Equipment>() 不支持将 ExpandoObject 作为其第二个参数。 - kkuilla
@kkuilla,你可以使用DynamicParameters,或者直接传递两个参数(dapper会忽略任何明显没有使用的参数)。 - Marc Gravell

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