C
C#2y ago
_vegabyte_

❔ Saving a JSON object to Database

HI. I want to save a Array to Database but I'm this error.
"Error getting value from 'Values' on 'ELIXIR.DATA.DATA_ACCESS_LAYER.MODELS.QC_CHECKLIST.CheckListString'.",
"Error getting value from 'Values' on 'ELIXIR.DATA.DATA_ACCESS_LAYER.MODELS.QC_CHECKLIST.CheckListString'.",
public class CheckListString
{
[Key]
public int ChecklistStringId { get; set; }
public int? PO_Summary_Id { get; set; }
public int? ReceivingId { get; set; }
public string Checlist_Type { get; set; }

[NotMapped]
public List<string> Values
{
get => JsonSerializer.Deserialize<List<string>>(Value);
set => Value = JsonSerializer.Serialize(value);
}
public string Value { get; set; }

public string Remarks { get; set; }
}
public class CheckListString
{
[Key]
public int ChecklistStringId { get; set; }
public int? PO_Summary_Id { get; set; }
public int? ReceivingId { get; set; }
public string Checlist_Type { get; set; }

[NotMapped]
public List<string> Values
{
get => JsonSerializer.Deserialize<List<string>>(Value);
set => Value = JsonSerializer.Serialize(value);
}
public string Value { get; set; }

public string Remarks { get; set; }
}
public async Task<bool> AddChecklists(Checklists input)
{
foreach (var checklistString in input.ChecklistsString)
{
var newChecklistString = new CheckListString
{
PO_Summary_Id = checklistString.PO_Summary_Id,
Checlist_Type = checklistString.Checlist_Type,
Values = checklistString.Values,
Remarks = checklistString.Remarks
};
await _context.CheckListStrings.AddAsync(newChecklistString);
}

await _context.SaveChangesAsync();

return true;
}
public async Task<bool> AddChecklists(Checklists input)
{
foreach (var checklistString in input.ChecklistsString)
{
var newChecklistString = new CheckListString
{
PO_Summary_Id = checklistString.PO_Summary_Id,
Checlist_Type = checklistString.Checlist_Type,
Values = checklistString.Values,
Remarks = checklistString.Remarks
};
await _context.CheckListStrings.AddAsync(newChecklistString);
}

await _context.SaveChangesAsync();

return true;
}
This is the body
{
"checklistsString": [
{
"checklistStringId": 0,
"pO_Summary_Id": 0,
"receivingId": 0,
"checlist_Type": "string",
"values": [
"string"
],
"value": "string",
"remarks": "string"
}
]
}
{
"checklistsString": [
{
"checklistStringId": 0,
"pO_Summary_Id": 0,
"receivingId": 0,
"checlist_Type": "string",
"values": [
"string"
],
"value": "string",
"remarks": "string"
}
]
}
Any help will be much appreciated
24 Replies
_vegabyte_
_vegabyte_OP2y ago
GitHub
ELIXIR-DEPOT/ChecklistRepository.cs at developmentenv · aldrin0408a...
A system that provides barcode technology to streamline the process and data visibility by tracking of inventories in Central Depot Plant - ELIXIR-DEPOT/ChecklistRepository.cs at developmentenv · a...
Jimmacle
Jimmacle2y ago
is there a reason you aren't using EF value converters?
Yawnder
Yawnder2y ago
I was about to ask the same, why the Values property?
_vegabyte_
_vegabyte_OP2y ago
Just new to this and I just found this approach to the internet
_vegabyte_
_vegabyte_OP2y ago
Sorry for the structure, I know its messed up
Yawnder
Yawnder2y ago
I can work, but the better approach would be a converter. Also, I'd suggest using ETCs (EntityTypeConfiguration) rather than attributes. It's a preference, but most seasoned EF devs would agree with that.
Jimmacle
Jimmacle2y ago
yeah i personally like ETC/fluent api over attributes, you'll inevitably need to use the fluent api at some point so might as well keep all configuration in the same place
_vegabyte_
_vegabyte_OP2y ago
Thanks for the advise. I'll try to rewrite it and use all the suggestion you've provided. But may I ask, what are the things need to change here?
Yawnder
Yawnder2y ago
Oh, and while you get started with ETCs, just to mention something: You don't need to tell EF everything. You only need to specify stuff that doesn't align with conventions or that can be ambiguous. What do you mean?
_vegabyte_
_vegabyte_OP2y ago
In code I've provided. What are the things need to change or need to consider in using ETC. It's kinda new to to me that's why
Yawnder
Yawnder2y ago
1- Have your Entity be a pure POCO. No method or fancy properties. 2- In your entity type configuration, just add a converter (use HasConversion(...)) to the field.
_vegabyte_
_vegabyte_OP2y ago
I will consider those. Thank you!!
Yawnder
Yawnder2y ago
@Minarii https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions?tabs=data-annotations#composite-value-objects Look at how they do it:
modelBuilder.Entity<Order>()
.Property(e => e.Price)
.HasConversion(
v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null),
v => JsonSerializer.Deserialize<Money>(v, (JsonSerializerOptions)null));
modelBuilder.Entity<Order>()
.Property(e => e.Price)
.HasConversion(
v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null),
v => JsonSerializer.Deserialize<Money>(v, (JsonSerializerOptions)null));
_vegabyte_
_vegabyte_OP2y ago
What if I need to store primitive vales public List<string> Values { get => JsonSerializer.Deserialize<List<string>>(Value); set => Value = JsonSerializer.Serialize(value); } All the Values has a value of string
Yawnder
Yawnder2y ago
Same difference
Jimmacle
Jimmacle2y ago
same thing, as far as EF is concerned it's just a complex type that can be converted to and from a string the converter tells EF how to translate a List<string> or whatever into something that can go into a column and vice versa
Yawnder
Yawnder2y ago
And the serializer (whether you're using Newtonsoft's or Microsoft's) will escape what needs to be escaped for proper serialization.
Jimmacle
Jimmacle2y ago
note that if you do this i don't think you'll be able to query into the list like you'd expect in LINQ
Yawnder
Yawnder2y ago
Anything that you store serialized should be considered "binary data" as long as it's in the database indeed.
Jimmacle
Jimmacle2y ago
technically since it's json you could write a raw query to do it if the DB supports json, but that's starting to get yucky i had a similar problem and ended up splitting the collections into tables so they play nice with EF
Yawnder
Yawnder2y ago
Yeah, but anything you do through EF wouldn't like it.
_vegabyte_
_vegabyte_OP2y ago
Hi everyone, finally the code is now running. Your suggestions are helpful! Thank you very much!
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CheckListString>()
.Property(e => e.Value)
.HasConversion(
v => JsonSerializer.Serialize(v, null),
v => JsonSerializer.Deserialize<List<string>>(v, null),
new ValueComparer<List<string>>(
(c1, c2) => c1.SequenceEqual(c2),
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
c => c.ToList()
));
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CheckListString>()
.Property(e => e.Value)
.HasConversion(
v => JsonSerializer.Serialize(v, null),
v => JsonSerializer.Deserialize<List<string>>(v, null),
new ValueComparer<List<string>>(
(c1, c2) => c1.SequenceEqual(c2),
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
c => c.ToList()
));
}
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?