问题
I'm not sure if there is a way to support this, but I'm having trouble getting Dapper to map string parameter values to the Postgresql citext data type as it seems to be using the text type.
In particular, I'm trying to call a function that takes in citext parameters - the error I get back is:
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.
The signature that would match is function dbo.MyFunction(citext, citext) so clearly it can't find it using the default mapping.
According to Npgsql - http://www.npgsql.org/doc/types.html I need to be able to specify NpgsqlDbType.Citext as the type but I can't find a way to do this using Dapper.
Solved thanks to answer from Shay, complete solution here:
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
});
}
}
回答1:
You probably need to create create a CitextParameter which extends ICustomQueryParameter. This API allows you to pass an arbitrary DbParameter instance to Dapper - in this case it would be an instance of NpgsqlParameter with its NpgsqlDbType set to Citext.
Something like this should work:
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
});
}
}
回答2:
When you write the SQL query, you can cast the parameter value like cast(@param as citext).
in my case below worked correctly. (usr is a class object)
string sql = "select * from users where user_name = cast(@user_name as citext) and password = @password;";
IEnumerable<users> u = cnn.Query<users>(sql, usr);
In your case, you can change the query like below and see if that works
string sql = @"select * from ""dbo"".""MyFunction""(cast(@schemaName as citext), cast(@tableName as citext));";
来源:https://stackoverflow.com/questions/39238507/using-dapper-and-postgresql-citext-data-type