I am creating a reusable library using .NET Core (targeting .NETStandard 1.4) and I am using Entity Framework Core (and new to both). I have an entity class that looks like
The key to making the the Change Tracker function correctly is to implement a ValueComparer as well as a ValueConverter. Below is an extension to implement such:
public static class ValueConversionExtensions
{
public static PropertyBuilder HasJsonConversion(this PropertyBuilder propertyBuilder) where T : class, new()
{
ValueConverter converter = new ValueConverter
(
v => JsonConvert.SerializeObject(v),
v => JsonConvert.DeserializeObject(v) ?? new T()
);
ValueComparer comparer = new ValueComparer
(
(l, r) => JsonConvert.SerializeObject(l) == JsonConvert.SerializeObject(r),
v => v == null ? 0 : JsonConvert.SerializeObject(v).GetHashCode(),
v => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(v))
);
propertyBuilder.HasConversion(converter);
propertyBuilder.Metadata.SetValueConverter(converter);
propertyBuilder.Metadata.SetValueComparer(comparer);
propertyBuilder.HasColumnType("jsonb");
return propertyBuilder;
}
}
Example of how this works.
public class Person
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string FirstName { get; set; }
[Required]
[MaxLength(50)]
public string LastName { get; set; }
[Required]
public DateTime DateOfBirth { get; set; }
public List Addresses { get; set; }
}
public class Address
{
public string Type { get; set; }
public string Company { get; set; }
public string Number { get; set; }
public string Street { get; set; }
public string City { get; set; }
}
public class PersonsConfiguration : IEntityTypeConfiguration
{
public void Configure(EntityTypeBuilder builder)
{
// This Converter will perform the conversion to and from Json to the desired type
builder.Property(e => e.Addresses).HasJsonConversion>();
}
}
This will make the ChangeTracker function correctly.