sqlite C#将具有字典的对象作为字段存储在SQL数据库中

qeeaahzv  于 2022-11-15  发布在  SQLite
关注(0)|答案(1)|浏览(140)

我有一长串精心制作的物品和一本试剂词典,其中包括一个int,一个是试剂的id,一个int,它是要使用的数量。
我不知道如何将此列表存储在表格中。

public class CraftedItem : IEquatable<CraftedItem>
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public Dictionary<int, int> ReagentsAndQuantities { get; set; }
    public int RecipeId { get; set; }

    public bool Equals(CraftedItem other)
    {
        if (other is null)
            return false;

        return Id == other.Id;
    }

    public override bool Equals(object obj) => Equals(obj as Recipe);
    public override int GetHashCode() => Id.GetHashCode();
}

当我在谷歌上搜索它时,我得到了很多关于如何使用词典的搜索结果,但关于如何存储一个以词典为成员的类却一无所获。有人能给我指个方向吗?

mm5n2pyu

mm5n2pyu1#

我根本不能和EF说话,但如果你只是使用普通的ADO连接,你只需要一个单独的表来存放你的词典:

create table crafted_item (
  id int primary key not null,
  name text,
  recipe_id int
);

create table reagents_and_quantities (
  crafted_item_id int not null,
  reagent int not null,
  quantity int,
  constraint reagents_and_quantities_pk primary key (crafted_item_id, reagent)
);

然后,诀窍就是您用来填充数据的CRUD。我会认为像这样简单的事情会奏效。假设您的CRUD getall方法如下所示:

List<CraftedItem> results = new List<CraftedItem>();

  using (NpgsqlCommand cmd = new NpgsqlCommand("select * from crafted_item", conn))
  {
      using (NpgSqlDataReader reader = cmd.ExecuteReader())
      {
          while (reader.Read())
          {
              CraftedItem foo = new CraftedItem();
              // populate the properties
              foo.ReagentsAndQuantities = new Dictionary<int, int>();
              results.Add(foo);
          }
          reader.Close();
      }
  }

然后,在关闭连接之前,执行另一遍操作并动态绑定词典条目:

using (NpgsqlCommand cmd = new NpgsqlCommand("select * from reagents_and_quantities", conn))
  {
      using (NpgSqlDataReader reader = cmd.ExecuteReader())
      {
          while (reader.Read())
          {
              int craftedItem = reader.GetInt32(0);
            
              CraftedItem foo = results.Find(x => x.Id == craftedItem);
              if (foo != null)
              {
                  int reagent = reader.GetInt32(1);
                  int qty = reader.GetInt32(2);
                  foo.ReagentsAndQuantities[reagent] = qty;
              }
          }
          reader.Close();
      }
  }

我有点懒,但希望你能明白。想必您的“getall”将具有某种形式的WHERE子句,因此您当然希望将其应用于reagents_and_Quantity细节以简化流程。
或者,您也可以使用JSON数据类型,但我不会费心。

相关问题