У меня есть функция PostgreSQL, которая принимает параметр типа json
.Используя Dapper, как мне выполнить вызов, который передает объект в функцию PostgreSQL, так что PostgreSQL распознает тип как json
вместо text
?
Пример функции PostgreSQL, которая принимает тип json
CREATE OR REPLACE FUNCTION testfuncthattakesinjson(heroes json)
RETURNS SETOF characters
LANGUAGE 'sql'
STABLE
ROWS 100
AS $BODY$
SELECT c.*
FROM characters c
JOIN json_array_elements(heroes) j
ON c.first_name = j->>'first_name'
AND c.last_name = j->>'last_name';
$BODY$;
Разбитый пример Тест интеграции C #
[Test]
public void Query_CallFunctionThatTakesInJsonParameter_FunctionUsesJsonType()
{
using (var conn = new NpgsqlConnection(Db.GetConnectionStringToDatabase()))
{
var funcName = "testfuncthattakesinjson";
var expect = CharacterTestData.Where(character => character.id <= 3);
var jsonObj = JArray.FromObject(CharacterTestData
.Where(character => character.id <= 3)
.Select(character => new Hero(character))
.ToList());
SqlMapper.AddTypeHandler(new JArrayTypeHandler());
// Act
var results = conn.Query<Character>(funcName, new
{
heroes = jsonObj
}, commandType: CommandType.StoredProcedure);
// Assert
CollectionAssert.AreEquivalent(expect, results);
}
}
Поддержка JArrayTypeHandler
internal class JArrayTypeHandler : SqlMapper.TypeHandler<JArray>
{
public override JArray Parse(object value)
{
throw new NotImplementedException();
}
public override void SetValue(IDbDataParameter parameter, JArray value)
{
parameter.Value = value;
}
}
В этомтекущую итерацию, я добавил SqlMapper.TypeHandler
.(В настоящее время я занимаюсь только передачей JArray
в PostgreSQL, следовательно, NotImplmentedException
для Parse
.)
В этом примере я получаю следующееисключение:
System.NotSupportedException : 'Тип массива CLR Newtonsoft.Json.Linq.JArray не поддерживается Npgsql или вашим PostgreSQL.Если вы хотите отобразить его в массив составных типов PostgreSQL, вам необходимо зарегистрировать его перед использованием, пожалуйста, обратитесь к документации. '
В прошлых итерациях я также пробовал такие вещи, как использование List<Hero>
обработчик типов и разрешение этому обработчику типов работать с преобразованием Json.
Я также пытался добавить расширение Npgsql.Json.NET
Nuget для Npgsql и вызвать conn.TypeMapper.UseJsonNet()
в моем тестовом методе, но это не так.Это, кажется, не имеет никакого эффекта.
И если я сделаю что-нибудь для сериализации объекта в строку JSON, то получу другую ошибку (ниже), которая имеет смысл.
Npgsql.PostgresException : '42883: функция testfuncthattakesinjson (heroes => text) не существует'
Таким образом, можно использовать Dapper для передачи объекта JSONкак примитив PostgreSQL для функции?