Home > database >  Store Dictionary<string, string> as List<KetValuePair<string, string>> in database
Store Dictionary<string, string> as List<KetValuePair<string, string>> in database

Time:09-22

I have an entity of type Dictionary<string, string> and I want to store it in a separate table as List<KetValuePair<string, string>>. This is what I am doing now

public class MyHttpLog
{
    public Guid Id
    public HttpRequestLog Request { get; set; }
}

public class HttpRequestLog
{
    public string Path { get; set; }
    public Dictionary<string, string> Headers { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyHttpLog>()
            .OwnsOne(b => b.Request, 
            request =>
            {
                request.WithOwner();
                request.Property(x => x.Headers).HasConversion(
                v => v.ToList(),
                v => JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonConvert.SerializeObject(v)) ?? new Dictionary<string, string>()
             );
    });
}

Since the object type is Dictionary, the relation in the model will be one to one but since we want to store it in the database as List, the relation will be one to many. How can I handle this? I don't want to convert the dictionary to serialized json. The error I am getting is

The property 'HttpRequestLog.Headers' is of type 'List<KeyValuePair<string, string>>' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

CodePudding user response:

try this :

public class MyHttpLog
{
    public Guid Id { get; set; }
    public HttpRequestLog Request { get; set; }
}

public class HttpRequestLog
{
    public int Id { get; set; }
    public string Path { get; set; }
    public Dictionary<string, string> Headers { get; set; }
}

public DbSet<MyHttpLog> MyHttpLog { get; set; }

public DbSet<HttpRequestLog> HttpRequestLog { get; set; }



protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   modelBuilder.Entity<HttpRequestLog>()
      .Property(b => b.Headers)
      .HasConversion(
       c => JsonConvert.SerializeObject(c),
       c => JsonConvert.DeserializeObject<Dictionary<string, string>>(c));
}

CodePudding user response:

You have two choices:

  1. Store your Key-Value pairs in completely separate table and reference it with a foreign key:

    public class MyKeyValuePairs
    {
        public string Key { get; set; }
        public string Value { get; set; }
        public int ForeignKey {get; set;}
    }
    
  2. Store your data in JSON format. Look this and this

  • Related