NPGSQL(PostgreSQL C#)JSON对象的插入阵列

发布于 2025-02-10 23:27:33 字数 3326 浏览 3 评论 0原文

我想将数据作为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软件包),

我还尝试制作一系列(JSON格式化)字符串来获得查询工作,从而可以理解的是例外,这可以理解。说我使用text []而不是JSON []

用C#NPGSQL实现这一目标真的很难吗?在其他语言中,例如JS(PG的NPM软件包),它非常容易。还是我想念S.Th。很明显吗?

注释:没有JSON []列查询的工作就像魅力一样。

高度赞赏一些帮助。谢谢!

I would like to insert data as array of json objects into a postgresql table column.

db table structure (create command for the table):

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

A working sql query example (with any sql client):

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

In npgsql I try it as following:

 //Create connection
        var connString = 
quot;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();

I have two classes from which I want generate the query params:

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

Since I was not able to do so, I tried to debug with hard coded stuff like this:

            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;

For the Json handling I use Newtonsoft.Json (Nuget Package)

I also tried to make an array of (json formatted) strings to get the query working which understandably lead to exceptions which say that I use text[] instead of json[].

Is it really that hard to achieve this with c# npgsql? In other languages like js (npm package of pg) it is super easy. Or am I missing s.th. very obvious?

Remark: without the json[] column the query works like a charm.

Some help is highly appreciated. Thx!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沧笙踏歌 2025-02-17 23:27:33

PostgreSQL的数组类型与JSON数组截然不同。换句话说,您无法将.Net Jarray(将PG JSON)映射到JSON [],这是您的列。取而代之的是,如下所示,请映射一个常规的.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,如上所述,打开这个问题使它变得更好。

最后,NPGSQL还支持内置System.Text.json作为newtonsoft.json的替代方案 - 为此不需要其他插件。

PostgreSQL has an array type which is very different from a JSON array; in other words, you can't write a .NET JArray (which maps to PG json) to json[], which is your column. Instead, map a regular .NET array of JObject as follows:

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

Note that you need to manually specify the NpgsqlDbType as in the above, opened this issue to make this better.

Finally, Npgsql also supports the built-in System.Text.Json as an alternative to Newtonsoft.Json - no additional plugin is needed for that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文