Как стать автором
Обновить

Комментарии 16

Не очень понял в чём отличие от хранения обычной строки и преобразовании в объект через HasConversation()?

Во-первых, это более простая в использовании, более наглядная и удобная альтернатива HasConversation(), вообще не требующая использовать Fluent API. Во вторых, тут доступна строгая сериализация, в том числе позволяющая поддерживать полиморфизм для сложных пользовательских классов, а не только базовых типов. Конечно, можно это реализовать и через Fluent API, но тогда будет еще больше лишнего кода, а тут готовый удобный функционал.

Две строчки кода, которые позволяют вообще не думать в большинстве случаев из-за использования проверенных временем сериализаторов, выглядят не так уж и плохо, чем работа с непонятным API, который к тому же будет просачиваться везде, потому что становится частью модели

Это будет не две строчки кода, если вам нужно поле типа List<object>, в котором значения типа int, double и decimal, инициализированные литералом "1", будут десериализованы при получении из бд как int , double и decimal, а не как int64 все трое. Или если вам нужно, чтобы поле типа BaseType десериализовалось как ChildType, если туда был записан объект такого типа.

Всё подводить к object вообще глупо из-за боксинга, который далеко не бесплатный, да и разнародный список уже говорит о том, что лучше уж сделать класс с полями/свойствами, чем поддерживать непонятно что, каждый раз думая, а что же там храниться

Когда вы добавляете внешнюю зависимость в проект в виде сторонней библиотеки — это уже само по себе рискованно и не очень хорошо:

  1. Зависимость это ещё одна дополнительная точка, которую постоянно, при обновлениях, потребуется проверять на уязвимость.

  2. Большинство разработчиков не имеют никакого опыта работы с большинством сторонних библиотек. Значит это дополнительная когнитивная нагрузка, усложнение дальнейшего развития и сопровождения, особенно когда зависимость просачивается в контракты и модели (вот это совсем плохо).

  3. Частенько, сторонние библиотеки перестают поддерживаться, и придётся переходить на форки.

Это не всё, конечно, но достаточно, чтоб не тащить в проект абсолютно любую фигню, чтобы сократить пару строк.

Если вы добавляете себе в проект зависимость, плюсы должны перевешивать все минусы. Это действительно должно быть решение, которое здорово облегчит вам жизнь и вы готовы мириться со всеми рисками.

Решение, которое вы описали к таковым, как мне кажется, не относится. Его можно изучить и даже кое что взять на вооружение, но задача решается "из коробки" — и вот этому стоило посвятить статью.

Как сложить 2+2? Берём библиотеку TwoPlusTwo и вуаля! Не надо так :)

Как минимум, задача записать в json-поле типа BaseType объект типа ChildType, а затем десериализовать значение именно последнего типа, не решается "из коробки" в EF

Не буду прям утверждать хорошо это или плохо, но я бы таки настоятельно советовал избегать наследования при сериализации/десериализации в JSON. Никаких стандартов на эту тему нет, а наследование в перспективе начнёт приносить всё меньше каких-либо выгод, и всё больше боли и страданий.

EFCore прекрасно поддерживает json поля без всяких сторонних библиотек и fluent api. Нужно просто правильно описать модельки.

Проверял на PostgreSQL и MySQL

Ну, во-первых, нет, без fluent api, на данный момент, в .net 7, невозможно настроить конвертацию в json. Во-вторых, придется постараться, чтобы json-поля поддерживали полиморфизм с точным преобразованием типов.

Мы видимо про разное?
Я на модельке просто делаю вот так и мои потребности закрывает.

[Column(TypeName = "jsonb")]
public Dictionary<string, string> Details { get; set; } = new();


Или так:
[Column("additional", TypeName = "json")] public MetaObject? Meta { get; set; } public class MetaObject { [JsonPropertyName("service")] public string Service { get; set; } = string.Empty; [JsonPropertyName("payout")] [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)] public decimal Payout { get; set; }
}

P.S. как тут код нормально отформатировать???

По крайней мере, с mssql такая запись не сработает. Может, вы не указали какие-то детали.

Даже если в некоторых условиях такая запись сработает, она всё-же не будет поддерживать полиморфизм.

P.S. для форматирования кода, поместите его в тройные косые кавычки (не знаю, как правильно назвать такие кавычки): " ``` "

С mssql не работал, там не знаю.
Для полиморфизма (точнее для чтения raw json, а потом что хочешь с ним, то и делай) у драйверов pgsql и mysql есть соответствующие типы, которые можно подставить в модельку.

Попробуй вот так
Попробуй вот так
record Sample ();

[Column("additional", TypeName = "json")]
public MetaObject? Meta { get; set; } 

public class MetaObject 
{ 
  [JsonPropertyName("service")] 
  public string Service { get; set; } = string.Empty; 
  
  [JsonPropertyName("payout")] 
  [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)] 
  public decimal Payout { get; set; }
}

У меня почему-то другой интерфейс, но разобрался.

Да, он ещё и Newtonsoft.Json использует...

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации