Я настраиваю приложение, которое использует EF Core в паре с PostgreSQL, используя драйвер npgsql. Я использую тип поля [jsonb] в PostgreSQL, но в моей модели данных он отображается только на строковое свойство.
public class MyModel
{
[Column(TypeName = "jsonb")]
public string JsonData { get; set; }
}
Я хотел бы получить доступ к полю JsonData в качестве свойства словаря. Приведенный ниже код работает, но мне кажется расточительным, поскольку JsonDataDictionary перестраивается при каждом обращении к нему (кэширование).
public class MyModel
{
[Column(TypeName = "jsonb")]
public string JsonData { get; set; }
public Dictionary<string,string> JsonDataDictionary
{
get
{
return JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonData);
}
}
}
Я мог бы сохранить десериализованный объект в первый раз, а затем возвращать его каждый раз. Но ... возможно, что свойство JsonData изменится, поэтому словарь необходимо перестроить.
public class MyModel
{
[Column(TypeName = "jsonb")]
public string JsonData { get; set; }
private Dictionary<string,string> JsonDataDictionary;
public Dictionary<string,string> JsonDataDictionary
{
get
{
if (_JsonDataDictionary == null)
{
_JsonDataDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonData);
}
return _JsonDataDictionary;
}
}
}
Я думал об использовании какого-либо флага для отслеживания «грязности» свойства JsonData, но кое-что из этого не выглядит наилучшей практикой.
public class MyModel
{
private string _JsonData;
private bool _JsonDataChanged = true;
[Column(TypeName = "jsonb")]
public string JsonData
{
get
{
return _JsonData;
}
set
{
_JsonData = value;
_JsonDataChanged = true;
}
}
private Dictionary<string,string> _JsonDataDictionary;
[NotMapped]
public Dictionary<string,string> JsonDataDictionary
{
get
{
if (_JsonDataDictionary == null || _JsonDataChanged)
{
_JsonDataDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(_JsonData);
_JsonDataChanged = false;
}
return _JsonDataDictionary;
}
}
}
Кто-нибудь знает лучший способ сделать это?
ЦЕЛИ: не запускать десериализацию каждый раз, когда вызывается словарь. Тратить как можно меньше циклов. Понимая, что EF Core иногда кэширует кучу этих объектов, я хочу, чтобы объекты словаря загружались только во время их первого доступа (или при изменении строки JsonData).
Я прочитал инициализацию Lazy, но поскольку JsonDataDictionary опирается на строку JsonData, я не думаю, что статическая природа Lazy будет работать. Смотри: https://docs.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization