2016-08-30 7 views
2

Я не уверен, есть ли способ поддержать это, но у меня возникли проблемы с получением Dapper для сопоставления значений параметров строки в тип данных Citext Postgresql, поскольку он, кажется, использует тип текста.Использование 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.

решаемые благодаря ответ от Шай, полное решение здесь:

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 
     }); 
    } 
} 

ответ

4

Вы, вероятно, нужно создать создать CitextParameter, который проходит ICustomQueryParameter. Этот 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 
     }); 
    } 
} 
+0

Это идеальное спасибо! На это не было тонны хитов Google, поэтому навсегда найти. –

0

Когда вы пишете запрос SQL, вы можете привести значение параметра, как литой (@param как CITEXT).

в моем случае ниже работал правильно. (USR является объектом класса)

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));";