JSON 序列化值转换不使用 EF Core 跟踪更改

Dav*_*ola 13 json entity-framework-core ef-core-2.1

我正在使用 EF Core 值转换。

https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions

我写了一个 JSON 序列化器转换器,如下所示:

private static ValueConverter<T, String> JsonValueConverter<T>()
{
    ValueConverter<T, String> jsonConverter = new ValueConverter<T, String>(
        v => JsonConvert.SerializeObject(v),
        v => JsonConvert.DeserializeObject<T>(v));
    return jsonConverter;
}
Run Code Online (Sandbox Code Playgroud)

在应用程序中实现:

protected override void OnModelCreating(ModelBuilder mb)
{    
   ...
   mb.Entity<MyObject>()
     .Property(p => p.MySerializableObject)
     .HasConversion(JsonValueConverter<MySerializableObject>());
   ...
}
Run Code Online (Sandbox Code Playgroud)

有用。

但是,当您对序列化对象内的属性进行更改时,EF Core 更改跟踪不会获取对MySerializableObject.

我假设有某种方法可以在对象级别强制执行此操作。我试图实施IEqualityComparerMySerializableObject但更改跟踪没有开始工作。

Dav*_*ola 24

我能够通过向属性的元数据添加 aValueConverter和 a来启动更改跟踪ValueComparer,但是,我的比较器可能非常低效。如果有人对此性能调整有建议,将不胜感激。

mb.Entity<MyObject>().Property(p => .MySerializableObject).HasJsonConversion();
Run Code Online (Sandbox Code Playgroud)

使用新的 HasJsonConversion 扩展方法

public static class ValueConversionExtensions
{
    public static PropertyBuilder<T> HasJsonConversion<T>(this PropertyBuilder<T> propertyBuilder)
    {           
        ValueConverter<T, String> converter = new ValueConverter<T, String>(
            v => JsonConvert.SerializeObject(v),
            v => JsonConvert.DeserializeObject<T>(v));

        ValueComparer<T> comparer = new ValueComparer<T>(
            (l, r) => JsonConvert.SerializeObject(l) == JsonConvert.SerializeObject(r),
            v => v == null ? 0 : JsonConvert.SerializeObject(v).GetHashCode(),
            v => JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(v)));

        propertyBuilder.HasConversion(converter);
        propertyBuilder.Metadata.SetValueConverter(converter);
        propertyBuilder.Metadata.SetValueComparer(comparer);            

        return propertyBuilder;
    }        
}
Run Code Online (Sandbox Code Playgroud)