json 如何将表中的数据重新组织为复杂的C#对象?

r9f1avp5  于 2023-08-08  发布在  C#
关注(0)|答案(5)|浏览(109)

我有一个表格,其中包含了对相同帖子的几个引用,它们本身包含了对相同语言的几个引用,就像这样:
| 语言学|名称,名称|价值| value |
| --|--|--| ------------ |
| 恩|标题|职位1标题| Post 1 title |
| 恩|身体|这是帖子1的内容| This is the content for the post 1 |
| 前|标题|第1条标题| Titre de l'article 1 |
| 前|身体|第一条内容| Voici le contenu de l'article 1 |
| 恩|标题|职位2标题| Post 2 title |
| 恩|身体|这是帖子2的内容| This is the content for the post 2 |
| 恩|标题|Post 3标题| Post 3 title |
| 恩|身体|这是帖子3的内容| This is the content for the post 3 |
| 前|标题|第3条标题| Titre de l'article 3 |
| 前|身体|第三条内容| Voici le contenu de l'article 3 |
| 德|标题|Titel von Artikel 3| Titel von Artikel 3 |
| 德|身体|Lesen Sie den Inhalt von Artikel 3| Lesen Sie den Inhalt von Artikel 3 |
基于这个表,我想创建一个C#对象,它可以集成到以下内容:

{
   "posts":[
      {
         "1":[
            {
               "en":{
                  "title":"Post 1 title",
                  "body":"This is the content for the post 1"
               }
            },
            {
               "fr":{
                  "title":"Titre de l'article 1",
                  "body":"Voici le contenu de l'article 1"
               }
            }
         ]
      },
      {
         "2":[
            {
               "en":{
                  "title":"Post 2 title",
                  "body":"This is the content for the post 2"
               }
            }
         ]
      },
      {
         "3":[
            {
               "en":{
                  "title":"Post 3 title",
                  "body":"This is the content for the post 3"
               }
            },
            {
               "fr":{
                  "title":"Titre de l'article 3",
                  "body":"Voici le contenu de l'article 3"
               }
            },
            {
               "de":{
                  "title":"Titel von Artikel 3",
                  "body":"Lesen Sie den Inhalt von Artikel 3"
               }
            }
         ]
      }
   ]
}

字符串

如何在C#中实现这一点?

在从SQL数据库中选择数据后,我循环遍历每一行,试图将其添加到字符串Dictionary<string, Dictionary<string, Dictionary<string, string>>>的字典中,测试该键是否存在于字典中。如果它存在,我只是赋值。如果没有,我添加键,然后赋值,如下所示:

Dictionary<string, Dictionary<string, Dictionary<string, string>>> postsDictionnary= new();

foreach(var post in postsList)
{
    if (postsDictionnary.ContainsKey(post.postId))
    {
        if (postsDictionnary[post.postId].ContainsKey(post.language))
        {
            if (postsDictionnary[post.itemId][post.language].ContainsKey(post.name))
            {
                postsDictionnary[post.itemId][post.language][post.name] = post.value;
            }
            else
            {
                postsDictionnary[post.postId][post.language].Add(post.name, post.value);
            }
        }
        else
        {
            postsDictionnary[post.postId].Add(post.language, new Dictionary<string, string>());
            postsDictionnary[post.postId][post.language].Add(post.name, post.value);
        }
    }
    else
    {
        postsDictionnary.Add(post.postId, new Dictionary<string, Dictionary<string, string>>());
        postsDictionnary[post.postId].Add(post.language, new Dictionary<string, string>());
        postsDictionnary[post.postId][post.language].Add(post.name, post.value);
    }
}


postsDictionnary组织得很好,但是**有没有更好的方法来实现这一点?**创建字符串的字典的字典。

g2ieeal7

g2ieeal71#

假设您有下面的类和这些对象的列表

public class Post
{
    public int PostId { get; set; }
    public string Language { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

字符串
然后你可以编写以下LINQ查询:

var posts = new List<Post>
{
    new Post { PostId = 1, Language = "en", Name = "title", Value = "Post 1 title" },
    new Post { PostId = 1, Language = "en", Name = "body", Value = "This is the content for the post 1" },
    new Post { PostId = 1, Language = "fr", Name = "title", Value = "Titre de l'article 1" },
    new Post { PostId = 1, Language = "fr", Name = "body", Value = "Voici le contenu de l'article 1" },
    new Post { PostId = 2, Language = "en", Name = "title", Value = "Post 2 title" },
    new Post { PostId = 2, Language = "en", Name = "body", Value = "This is the content for the post 2" },
    new Post { PostId = 3, Language = "en", Name = "title", Value = "Post 3 title" },
    new Post { PostId = 3, Language = "en", Name = "body", Value = "This is the content for the post 3" },
    new Post { PostId = 3, Language = "fr", Name = "title", Value = "Titre de l'article 3" },
    new Post { PostId = 3, Language = "fr", Name = "body", Value = "Voici le contenu de l'article 3" },
    new Post { PostId = 3, Language = "de", Name = "title", Value = "Titel von Artikel 3" },
    new Post { PostId = 3, Language = "de", Name = "body", Value = "Lesen Sie den Inhalt von Artikel 3" }
};

var result = posts
    .GroupBy(x => 1)
    .ToDictionary(x => "posts",
        p => p.GroupBy(bp => bp.PostId)
            .ToDictionary(bp => bp.Key,
                bp => bp.GroupBy(lp => lp.Language)
                    .ToDictionary(lp => lp.Key, lp => lp.ToDictionary(n => n.Name, n => n.Value))
            )
    );

au9on6nz

au9on6nz2#

我想你需要把这个DataTable转换成JSON。为此,您可以使用.NET中的Newtonsoft Json库并将数据序列化为有效的JSON。
大概是这样的:

string result;
result = JsonConvert.SerializeObject(dt); //where dt is content of DataTable

字符串
更多信息Newtonsoft Json

ctrmrzij

ctrmrzij3#

为什么不创建一个表示该对象类呢?
下面是一个可以用于您示例的类:

internal class Post
{
    public int PostId { get; set; }
    public string Language { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

字符串
要将SQL查询的结果转换为该类的示例,可以使用ORM。对于这个例子,你可能想使用一个微型ORM,比如dapper,他会看到这个链接https://www.learndapper.com/dapper-query/selecting-multiple-rows

using (var connection = new SqlConnection(connectionString))
{
    var sql = "SELECT * FROM yourTable"; // Careful: perf! You might want filters
    var posts = await connection.QueryAsync<Post>(sql);
    
    foreach(var post in posts)
    {
        Console.WriteLine($"{post.PostId} {post.Language} {post.Name} {post.Value}");
    }
}


一些可以使用LINQ执行的查询示例:

var engPosts = posts.Where(x=>x.Language == "ENG").ToList();
var allTittles = posts.Where(x=>x.Name=="Title").ToList();


请记住,根据您的用例,您可能希望在此数据结构之上使用其他数据结构,以提高性能,可用性,搜索等。

sirbozc5

sirbozc54#

您可以创建一个对象模型,由包含不同语言内容的帖子组成。

public class Content
{
    public string Title { get; set; }
    public string Body { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public Dictionary<string, Content> LocalizedContent { get; } = new();
}

字符串
范例:

List<Post> posts = new();

var post = new Post { Id = 1 };
post.LocalizedContent["en"] = new Content { 
    Title = "Post 1 title", 
    Body = "This is the content for the post 1"
};
post.LocalizedContent["fr"] = new Content {
    Title = "Titre de l'article 1",
    Body = "Voici le contenu de l'article 1"
};
posts.Add(post);


一个帖子包含一个内容字典,其中语言被用作关键词。这允许您向帖子添加不同的本地化内容。
在DB中,您将有两个表:

TABLE Post
    Id int PRIMARY KEY

TABLE Content
    PostId int PRIMARY KEY, FOREIGN KEY
    Language char(2) PRIMARY KEY
    Title varchar(80)
    Body varchar(max)


语言也可以是包含支持的语言沿着完整语言名称的语言表中的外键。

cngwdvgl

cngwdvgl5#

对于喜欢C#严格代码的人

var result = new Dictionary<int, Dictionary<string, PostItem>>();
    
    var postsG = posts.GroupBy(p => new { p.PostId });
    foreach (var item in postsG)
    {
        var posGG = item.GroupBy(i => i.Language);
        var dict = new Dictionary<string, Item>();
        foreach (var p in posGG)
        {
            var i = new PostItem();
            foreach (var pp in p)
                if (pp.Name == "title") i.title = (string)pp.Value;
                else i.body = (string)pp.Value;
            dict.Add(p.Key, i);
        }
        result.Add(item.Key.PostId, dict);
    }

public class PostItem
{
    public string title { get; set; }
    public string body { get; set; }
}

字符串
输出量

JsonConvert.SerializeObject(result, Newtonsoft.Json.Formatting.Indented);

{
  "1": {
    "en": {
      "title": "Post 1 title",
      "body": "This is the content for the post 1"
    },
    "fr": {
      "title": "Titre de l'article 1",
      "body": "Voici le contenu de l'article 1"
    }
  },
  "2": {
    "en": {
      "title": "Post 2 title",
      "body": "This is the content for the post 2"
    }
  },
  "3": {
    "en": {
      "title": "Post 3 title",
      "body": "This is the content for the post 3"
    },
    "fr": {
      "title": "Titre de l'article 3",
      "body": "Voici le contenu de l'article 3"
    },
    "de": {
      "title": "Titel von Artikel 3",
      "body": "Lesen Sie den Inhalt von Artikel 3"
    }
  }
}

相关问题