首页 > 解决方案 > UWP - 比较 JSON 和数据库上的数据

问题描述

我有一个名为 ebookstore.db 的数据库,如下所示: 数据库

和 JSON 如下: JSON

我希望当 JSON 上的 slug 与数据库中的标题不同时,它将显示 JSON 上的 slug 与 ukomikText 中数据库中的标题不同的数据量。

代码:

    string judulbuku;
     try
     {
        string urlPath1 = "https://...";
        var httpClient1 = new HttpClient(new HttpClientHandler());
        httpClient1.DefaultRequestHeaders.TryAddWithoutValidation("KIAT-API-KEY", "....");
        var values1 = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("halaman", 1),
            new KeyValuePair<string, string>("limit", 100),
        };

         var response1 = await httpClient1.PostAsync(urlPath1, new FormUrlEncodedContent(values1));
         response1.EnsureSuccessStatusCode();

        if (!response1.IsSuccessStatusCode)
        {
            MessageDialog messageDialog = new MessageDialog("Memeriksa update Komik gagal", "Gangguan Server");
            await messageDialog.ShowAsync();
        }
        string jsonText1 = await response1.Content.ReadAsStringAsync();
        JsonObject jsonObject1 = JsonObject.Parse(jsonText1);
        JsonArray jsonData1 = jsonObject1["data"].GetArray();

        foreach (JsonValue groupValue in jsonData1)
        {
            JsonObject groupObject = groupValue.GetObject();

            string id = groupObject["id"].GetString();
            string judul = groupObject["judul"].GetString();
            string slug = groupObject["slug"].GetString();

            BukuUpdate file1 = new BukuUpdate();
            file1.ID = id;
            file1.Judul = judul;
            file1.Slug = slug;

            List<String> title = sqlhelp.GetKomikData();
            foreach (string juduldb in title)
            {
                judulbuku = juduldb.Substring(juduldb.IndexOf('.') + 1);
                if (judulbuku != file1.Slug.Replace("-", "_") + ".pdf")
                {
                    BukuData.Add(file1);
                    ListBuku.ItemsSource = BukuData;
                }
                else
                {
                    ukomikText.Text = "belum tersedia komik yang baru";
                    ukomikText.Visibility = Visibility.Visible;
                }
            }
        }
        if (ListBuku.Items.Count > 0)
        {
            ukomikText.Text = BukuData.Count + " komik baru";
            ukomikText.Visibility = Visibility.Visible;
            jumlahbuku = BukuData.Count;
        }
        else
        {
            ukomikText.Text = "belum tersedia komik yang baru";
            ukomikText.Visibility = Visibility.Visible;
        }

 public static List<String> GetKomikData()
        {
            List<String> entries = new List<string>();

            using (SqliteConnection db =
                new SqliteConnection("Filename=ebookstore.db"))
            {
                db.Open();
                SqliteCommand selectCommand = new SqliteCommand
                    ("SELECT title FROM books where folder_id = 67", db);
                SqliteDataReader query = selectCommand.ExecuteReader();
                while (query.Read())
                {
                    entries.Add(query.GetString(0));
                }
                db.Close();
            }
            return entries;
        }

BukuUpdate.cs:

public string ID { get; set; }
public string Judul { get; set; }
public string Slug { get; set; }

我有一个问题,即在检查 JSON 上的 slug 时,显示的 slug 是第一个 slug 在数据库中重复显示尽可能多的数据,之后在数据库中重复显示第二个 slug,依此类推, 如下: 结果

如何解决让JSON上的slug不重复显示(根据JSON上的数据量)?

标签: c#jsondatabaseuwp

解决方案


问题是你有两个嵌套foreach循环。代码在简化伪代码中的作用:

For each item in JSON
   Load all rows from DB
   And for each loaded row
      Check if the current JSON item matches the row from DB and if not, output

如您所见,如果您N在 JSON 中有项目并且M在数据库中有行,这不可避免地会导致N*M输出行,除了那些 JSON 项目与数据库中特定行匹配的罕见行。

如果我理解正确,我假设您想检查是否存在与 JSON 项匹配的行,如果没有,则输出它。您可以通过以下方式执行此操作:

List<String> title = sqlhelp.GetKomikData();
HashSet<string> dbItems = new HashSet<string>();
foreach (string juduldb in title)
{
    judulbuku = juduldb.Substring(juduldb.IndexOf('.') + 1);
    dbItems.Add( judulbuku );
}

...

foreach ( JsonValue groupValue in jsonData1 )
{
    ...

    //instead of the second foreach

    if ( !dbItems.Contains( file1.Slug.Replace("-", "_") + ".pdf" ) )
    {
         //item is not in database
    }
    else
    {
         //item is in database
    }
}

其他提示

  • 避免GetKomikDataforeach. 此方法没有任何参数,这意味着您只是无缘无故地一次又一次地访问数据库,这需要时间并显着减慢执行速度。相反,GetKomikData在第一次之前只调用一次foreach,然后只使用title变量。
  • 不要在ItemsSource每次集合更改时分配。这将不必要地减慢 UI 线程,因为它必须在每个循环中重新加载所有项目。相反,在外部之后只分配一次属性foreach
  • 用一种语言编写代码。当您开始混合使用英语和印度尼西亚语的变量名称时,代码会变得混乱且可读性降低,并且会增加认知开销。
  • 避免使用非描述性变量名称,例如file1or jsonObject1。变量名应该清楚并告诉你它包含什么。当末尾有数字时,通常表示可以更清楚地命名。
  • 对列表变量名使用复数 - 而不是title使用titles

推荐阅读