【问题标题】:npgsql (postgresql c#) insert array of json objectsnpgsql(postgresql c#)插入json对象数组
【发布时间】:2022-11-11 10:52:13
【问题描述】:

我想将数据作为 json 对象数组插入到 postgresql 表列中。

db 表结构(为表创建命令):

CREATE TABLE Recipes (
key SERIAL PRIMARY KEY,
name varchar(255) NOT NULL,    
ingredients json[],
duration int);

一个有效的 sql 查询示例(使用任何 sql 客户端):

INSERT INTO
recipes (name, duration, ingredients)
VALUES(
'title',
60,
array['{"name": "in1",
"amount": 125,
"unit": "g" }',
'{ "name": "in2",
"amount": 75,
"unit": "ml" }'
]::json[]);

在 npgsql 我尝试如下:

 //Create connection
        var connString = $"Host={host};Port={port};Username={user};Password={password};Database={database}";
        Npgsql.NpgsqlConnection.GlobalTypeMapper.UseJsonNet();
 

        await using var conn = new NpgsqlConnection(connString);
        await conn.OpenAsync();
 //create query command
     await using var cmd = new NpgsqlCommand("INSERT INTO recipes (name,duration,ingredients) VALUES (@p0,@p1,@p2)", conn)
            {

                Parameters =
                    {                                                       
                        new NpgsqlParameter("p0", recipe.Name),                            
                        new NpgsqlParameter("p1", recipe.Duration),                            
                        new NpgsqlParameter("p2", recipe.Ingredients)
                    }
            };
 //execute query
    await cmd.ExecuteNonQueryAsync();

我有两个要从中生成查询参数的类:

public class Recipe
{
    public Recipe() { }
    public string Name { get; set; }
    public int Duration { get; set; }

    //tried this --> did not help
    //[Column(TypeName = "jsonb")]
    public Ingredients[] Ingredients { get; set; }

}

public class Ingredients
{
    public string Name { get; set; }
    public float Amount { get; set; }
    public string Unit { get; set; }
}

由于我无法这样做,因此我尝试使用如下硬编码的内容进行调试:

            JObject jsonObject1 = new JObject();
            jsonObject1.Add("name", "value1");
            jsonObject1.Add("amount", 1);
            jsonObject1.Add("unit", "ml");

            JObject jsonObject2 = new JObject();
            jsonObject2.Add("name", "value2");
            jsonObject2.Add("amount", 2);
            jsonObject2.Add("unit", "g");

            JObject jsonObject = new JObject();
            jsonObject.Add("name", "value0");
            jsonObject.Add("amount", 19);
            jsonObject.Add("unit", "ts");

            //OPTION 1 to insert into the query command instead of recipe.Ingredients
            JArray ingredientsJArray = new JArray();
            ingredientsJArray.Add(jsonObject1);
            ingredientsJArray.Add(jsonObject2);
            ingredientsJArray.Add(jsonObject);

            //AND OPTION 2 to insert into the query command instead of recipe.Ingredients
            JObject[] ingredientsArray = new JObject[3];
            ingredientsArray[0] = jsonObject;
            ingredientsArray[1] = jsonObject1;
            ingredientsArray[2] = jsonObject2;

对于 Json 处理,我使用 Newtonsoft.Json (Nuget Package)

我还尝试创建一个(json 格式)字符串数组以使查询正常工作,这可以理解地导致异常,即我使用text[] 而不是json[]

用 c# npgsql 实现这一点真的那么难吗?在其他语言中,例如 js(pg 的 npm 包),这非常容易。或者我错过了什么。很明显?

评论:没有json[] 列,查询就像一个魅力。

非常感谢一些帮助。谢谢!

【问题讨论】:

    标签: c# json postgresql sql-insert npgsql


    【解决方案1】:

    PostgreSQL 的数组类型与 JSON 数组非常不同;换句话说,您不能将 .NET JArray(映射到 PG json)写入您的专栏 json[]。相反,按如下方式映射 JObject 的常规 .NET 数组:

    var jsonObject1 = new JObject
    {
        { "name", "value1" },
        { "amount", 1 },
        { "unit", "ml" }
    };
    
    var jsonObject2 = new JObject
    {
        { "name", "value2" },
        { "amount", 2 },
        { "unit", "g" }
    };
    
    cmd.CommandText = "INSERT INTO Recipes (ingredients) VALUES (@p)";
    cmd.Parameters.Add(new("p", NpgsqlDbType.Json | NpgsqlDbType.Array) { Value = new[] { jsonObject1, jsonObject2 } });
    await cmd.ExecuteNonQueryAsync();
    

    请注意,您需要像上面一样手动指定 NpgsqlDbType,打开 this issue 以使其更好。

    最后,Npgsql 还支持内置的 System.Text.Json 作为 Newtonsoft.Json 的替代品——不需要额外的插件。

    【讨论】:

    • 非常感谢您快速准确的回答。现在可以了。不能投票,因为我还没有足够的声誉,但我希望其他人也这样做! :)
    猜你喜欢
    • 2018-07-05
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 2019-11-01
    • 2018-12-10
    • 2020-07-18
    • 1970-01-01
    • 2013-11-05
    相关资源
    最近更新 更多