I have a domain entity in my code where i have property Parameters
which is of type Dictionary<string, object>
. I have tried to add JsonConvert
. But the data gets changed while storing in db.
Task.cs
public sealed class Task
{
public Guid TaskId { get; set; }
public Guid QueryId { get; set; }
public Guid DatabaseId { get; set; }
public Guid OrganizationId { get; set; }
public DateTime CreatedOn = DateTime.UtcNow;
public string Status { get; set; } = string.Empty;
public IDictionary<string, object> Parameters { get; set; } = new Dictionary<string, object>();
}
DbContext.cs
public interface IDbContext
{
DbSet<Task> Tasks { get; }
Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess = true, CancellationToken cancellationToken = default);
}
internal sealed class QueryHubDbContext : DbContext, IQueryHubDbContext
{
public QueryHubDbContext(DbContextOptions<QueryHubDbContext> options)
: base(options)
{
}
public DbSet<Task> Tasks => Set<Task>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Query>(entity =>
{
entity.Property(e => e.Id).ValueGeneratedNever();
entity.Property(e => e.Tags)
.HasConversion(
v => string.Join(',', v.Where(tag => !string.IsNullOrWhiteSpace(tag))),
v => v.Split(',', StringSplitOptions.RemoveEmptyEntries));
});
modelBuilder.Entity<Task>(ConfigureTask);
base.OnModelCreating(modelBuilder);
}
private void ConfigureTask(EntityTypeBuilder<Task> builder)
{
builder.HasKey(e => e.TaskId);
builder.Property(e => e.TaskId).ValueGeneratedNever();
builder.Property(e => e.Parameters)
.HasConversion(
v => JsonConvert.SerializeObject(v),
v => JsonConvert.DeserializeObject<Dictionary<string, object>>(v) ?? new Dictionary<string, object>())
.HasColumnType("nvarchar(max)");
}
}
with these configuration i when i pass
{
"taskId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"queryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"databaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "string",
"parameters": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
Data stored in the db ->
{
"taskId": "9abf0000-76ab-40b0-d1d5-08dbf0421eaa",
"queryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"databaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "",
"parameters": {
"additionalProp1": {
"valueKind": []
},
"additionalProp2": {
"valueKind": []
},
"additionalProp3": {
"valueKind": []
}
}
}
I am using SqlServer as my Db. There exist a db type "json" or "jsonb" for postgres. There doesnt for sql server.
I tested pass the data with some difference having no problem.
Task.cs
public class Task
{
[Key]
public int Id { get; set; }
public Dictionary<string, object> Parameters { get; set; } = new Dictionary<string, object>();
}
MyContext.cs
public class MyContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySql("server=192.168.2.68;database=wa76;user=mysql1;password=xxxxx", new MySqlServerVersion(new Version()));
}
public DbSet<Task> TaskTable { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Task>()
.Property(b => b.Parameters)
.HasConversion(
v => JsonConvert.SerializeObject(v),
v => JsonConvert.DeserializeObject<Dictionary<string, object>>(v));
}
}
controller
[HttpPost("test")]
public void test(object obj)
{
var model = JsonConvert.DeserializeObject<Task>(obj.ToString());
_context.Add(model);
_context.SaveChanges();
}