使用 Dapper 和 Postgresql - citext 数据类型
Using Dapper and Postgresql - citext data type
我不确定是否有办法支持这一点,但我无法让 Dapper 将字符串参数值映射到 Postgresql citext 数据类型,因为它似乎正在使用文本类型。
特别是,我试图调用一个接受 citext 参数的函数 - 我得到的错误是:
var c = ConnectionManager<T>.Open();
string sql = @"select * from ""dbo"".""MyFunction""(@schemaName, @tableName);";
var param = new
{
schemaName = schema,
tableName = table
};
string insecureSalt = c.QueryMultiple(sql, param).Read<string>().FirstOrDefault();
ConnectionManager<T>.Close(c);
Error: Npgsql.PostgresException: 42883: function dbo.MyFunction(text, text) does not exist.
匹配的签名是函数 dbo.MyFunction(citext, citext) 很明显它无法使用默认映射找到它。
根据 Npgsql - http://www.npgsql.org/doc/types.html 我需要能够将 NpgsqlDbType.Citext 指定为类型,但我找不到使用 Dapper 执行此操作的方法。
已解决 感谢 Shay 的回答,完整的解决方案在这里:
var c = ConnectionManager<T>.Open();
string sql = @"select * from ""dbo"".""MyFunction""(@schemaName, @tableName);";
var param = new
{
schemaName = new CitextParameter(schema),
tableName = new CitextParameter(table)
};
string insecureSalt = c.QueryMultiple(sql, param).Read<string>().FirstOrDefault();
ConnectionManager<T>.Close(c);
public class CitextParameter : SqlMapper.ICustomQueryParameter
{
readonly string _value;
public CitextParameter(string value)
{
_value = value;
}
public void AddParameter(IDbCommand command, string name)
{
command.Parameters.Add(new NpgsqlParameter
{
ParameterName = name,
NpgsqlDbType = NpgsqlDbType.Citext,
Value = _value
});
}
}
您可能需要创建一个扩展 ICustomQueryParameter 的 CitextParameter。 API 允许您将任意 DbParameter 实例传递给 Dapper - 在这种情况下,它将是 NpgsqlParameter 的实例,其 NpgsqlDbType 设置为 Citext。
像这样的东西应该可以工作:
class CitextParameter : SqlMapper.ICustomQueryParameter
{
readonly string _value;
public CitextParameter(string value)
{
_value = value;
}
public void AddParameter(IDbCommand command, string name)
{
command.Parameters.Add(new NpgsqlParameter
{
ParameterName = name,
NpgsqlDbType = NpgsqlDbType.Citext,
Value = _value
});
}
}
写SQL查询时,可以像cast(@param as citext)这样强制转换参数值。
在我的案例中,下面的代码工作正常。 (usr 是一个 class 对象)
string sql = "select * from users where user_name = cast(@user_name as citext) and password = @password;";
IEnumerable<users> u = cnn.Query<users>(sql, usr);
对于您的情况,您可以像下面这样更改查询,看看是否可行
string sql = @"select * from ""dbo"".""MyFunction""(cast(@schemaName as citext), cast(@tableName as citext));";
我不确定是否有办法支持这一点,但我无法让 Dapper 将字符串参数值映射到 Postgresql citext 数据类型,因为它似乎正在使用文本类型。
特别是,我试图调用一个接受 citext 参数的函数 - 我得到的错误是:
var c = ConnectionManager<T>.Open();
string sql = @"select * from ""dbo"".""MyFunction""(@schemaName, @tableName);";
var param = new
{
schemaName = schema,
tableName = table
};
string insecureSalt = c.QueryMultiple(sql, param).Read<string>().FirstOrDefault();
ConnectionManager<T>.Close(c);
Error: Npgsql.PostgresException: 42883: function dbo.MyFunction(text, text) does not exist.
匹配的签名是函数 dbo.MyFunction(citext, citext) 很明显它无法使用默认映射找到它。
根据 Npgsql - http://www.npgsql.org/doc/types.html 我需要能够将 NpgsqlDbType.Citext 指定为类型,但我找不到使用 Dapper 执行此操作的方法。
已解决 感谢 Shay 的回答,完整的解决方案在这里:
var c = ConnectionManager<T>.Open();
string sql = @"select * from ""dbo"".""MyFunction""(@schemaName, @tableName);";
var param = new
{
schemaName = new CitextParameter(schema),
tableName = new CitextParameter(table)
};
string insecureSalt = c.QueryMultiple(sql, param).Read<string>().FirstOrDefault();
ConnectionManager<T>.Close(c);
public class CitextParameter : SqlMapper.ICustomQueryParameter
{
readonly string _value;
public CitextParameter(string value)
{
_value = value;
}
public void AddParameter(IDbCommand command, string name)
{
command.Parameters.Add(new NpgsqlParameter
{
ParameterName = name,
NpgsqlDbType = NpgsqlDbType.Citext,
Value = _value
});
}
}
您可能需要创建一个扩展 ICustomQueryParameter 的 CitextParameter。 API 允许您将任意 DbParameter 实例传递给 Dapper - 在这种情况下,它将是 NpgsqlParameter 的实例,其 NpgsqlDbType 设置为 Citext。
像这样的东西应该可以工作:
class CitextParameter : SqlMapper.ICustomQueryParameter
{
readonly string _value;
public CitextParameter(string value)
{
_value = value;
}
public void AddParameter(IDbCommand command, string name)
{
command.Parameters.Add(new NpgsqlParameter
{
ParameterName = name,
NpgsqlDbType = NpgsqlDbType.Citext,
Value = _value
});
}
}
写SQL查询时,可以像cast(@param as citext)这样强制转换参数值。
在我的案例中,下面的代码工作正常。 (usr 是一个 class 对象)
string sql = "select * from users where user_name = cast(@user_name as citext) and password = @password;";
IEnumerable<users> u = cnn.Query<users>(sql, usr);
对于您的情况,您可以像下面这样更改查询,看看是否可行
string sql = @"select * from ""dbo"".""MyFunction""(cast(@schemaName as citext), cast(@tableName as citext));";