I have used "HasConversion" in my DBContext to define a JSonArray (Language/Value) and save it as a Text field for ages and It works like a charm, I added a new project to my solution, nothing changed but then I got a new error on adding migration regarding "setting a value comparer".
My Model is like:
public class Brand
{
public int Id { get; set; }
public new IList<LangValue> Name { get; set; } = new List<LangValue>();
}
and DBContext is like:
modelBuilder.Entity<Brand>(t =>
{
t.Property(p => p.Name).HasConversion(
v => JsonConvert.SerializeObject(v, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Include}),
v => JsonConvert.DeserializeObject<IList<LangValue>>(v, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Include})
);
});
It was working perfectly, but after adding a new project I got Yellow error in adding migration and Model does not add to the new database.
Microsoft.EntityFrameworkCore.Model.Validation[10620] The property 'Name' on entity type 'Brand' is a collection or enumeration type with a value converter but with no value comparer. Set a value comparer to ensure the collection/enumeration elements are compared correctly.
Value converters allow property values to be converted when reading from or writing to the database.
To use Entity Framework 6, your project has to compile against . NET Framework, as Entity Framework 6 doesn't support . NET Core. If you need cross-platform features you will need to upgrade to Entity Framework Core.
IEntityTypeConfiguration<TEntity> InterfaceAllows configuration for an entity type to be factored into a separate class, rather than in-line in OnModelCreating(ModelBuilder).
The explanation from ValueComparer docs https://docs.microsoft.com/en-us/ef/core/modeling/value-comparers#mutable-classes
A typical value conversion on a list property might convert the list to and from JSON:
modelBuilder
.Entity<EntityType>()
.Property(e => e.MyProperty)
.HasConversion(
v => JsonSerializer.Serialize(v, null),
v => JsonSerializer.Deserialize<List<int>>(v, null));
This then requires setting a ValueComparer<T>
on the property to force EF Core use correct comparisons with this conversion:
var valueComparer = new ValueComparer<List<int>>(
(c1, c2) => c1.SequenceEqual(c2),
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
c => c.ToList());
modelBuilder
.Entity<EntityType>()
.Property(e => e.MyProperty)
.Metadata
.SetValueComparer(valueComparer);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With