dev*_*309 4 c# postgresql dapper
我有一个 PostgreSQL 函数,它接受一个类型为 的参数json。使用 Dapper,我如何执行将对象传递给 PostgreSQL 函数的调用,以便 PostgreSQL 将类型识别为 asjson而不是 as text?
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$;
Run Code Online (Sandbox Code Playgroud)
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在当前的迭代中,我添加了一个SqlMapper.TypeHandler. (目前,我只关心将 传递JArray 给PostgreSQL,因此是NotImplmentedExceptionfor Parse。)
在这个例子中,我得到以下异常:
System.NotSupportedException : 'Npgsql 或您的 PostgreSQL 不支持 CLR 数组类型 Newtonsoft.Json.Linq.JArray。如果您希望将其映射到 PostgreSQL 复合类型数组,您需要在使用前注册它,请参阅文档。
在过去的迭代中,我还尝试过使用List<Hero>类型处理程序并让该类型处理程序处理 Json 转换等方法。
我还尝试Npgsql.Json.NET为 Npgsql添加Nuget 包扩展并调用conn.TypeMapper.UseJsonNet()我的测试方法,但这似乎没有任何效果。
如果我执行任何操作将对象序列化为 JSON 字符串,那么我会收到一个不同的错误(如下),这是有道理的。
Npgsql.PostgresException : '42883: 函数 testfuncthattakesinjson(heroes => text) 不存在'
那么,是否可以使用 Dapper 将 JSON 对象作为 PostgreSQL 原语传递给函数?
小智 5
您可以使用 Dapper 的 ICustomQueryParameter 接口。
public class JsonParameter : ICustomQueryParameter
{
private readonly string _value;
public JsonParameter(string value)
{
_value = value;
}
public void AddParameter(IDbCommand command, string name)
{
var parameter = new NpgsqlParameter(name, NpgsqlDbType.Json);
parameter.Value = _value;
command.Parameters.Add(parameter);
}
}
Run Code Online (Sandbox Code Playgroud)
然后你的 Dapper 电话变成:
var results = conn.Query<Character>(funcName, new
{
heroes = new JsonParameter(jsonObj.ToString())
}, commandType: CommandType.StoredProcedure);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2538 次 |
| 最近记录: |