Using Dapper and Postgresql - citext data type

五迷三道 提交于 2021-02-07 21:49:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!