Как сохранить список строк с помощью Entity Framework Core?
===========================================================

 Предположим, что у нас есть один класс, который выглядит следующим образом: 

```
public class Entity
{
    public IList<string> SomeListOfValues { get; set; }

    // Other code
}

```
  Теперь предположим, что мы хотим сохранить это с использованием EF Core Code First и что мы используем RDMBS, такой как SQL Server. 

 Один из возможных подходов, очевидно, заключается в создании Wraper класса `Wraper` который обертывает строку: 

```
public class Wraper
{
    public int Id { get; set; }

    public string Value { get; set; }
}

```
  И для реорганизации класса, чтобы теперь он `Wraper` от `Wraper` объектов `Wraper` . В этом случае EF создаст таблицу для `Entity` , таблицу для `Wraper` и установит отношение «один ко многим»: для каждого объекта существует куча оберток. 

 Хотя это работает, мне не совсем нравится этот подход, потому что мы меняем очень простую модель из-за проблем с сохранением. Действительно, думая о модели домена и коде, без настойчивости, класс `Wraper` здесь совершенно бессмыслен. 

 Есть ли другой способ сохранения одного объекта со списком строк в СУРБД с использованием основного кода EF First, кроме создания класса wraper? Конечно, в конечном итоге нужно сделать то же самое: нужно создать другую таблицу, чтобы удерживать строки, а отношения «один ко многим» должны быть на месте. Я просто хочу сделать это с помощью EF Core без необходимости кодировать класс wraper в модели домена. 

 Это может быть достигнуто гораздо более простым способом, начиная с Entity Framework Core **2.1** . EF теперь поддерживает [преобразование значений,](https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions) чтобы специально адресовать сценарии, подобные этому, где свойство должно быть сопоставлено с другим типом для хранения. 

 Чтобы сохранить коллекцию строк, вы можете настроить ваш `DbContext` следующим образом: 

```
protected override void OnModelCreating(ModelBuilder builder)
{
    var splitStringConverter = new ValueConverter<IEnumerable<string>, string>(v => string.Join(";", v), v => v.Split(new[] { ';' }));
    builder.Entity<Entity>().Property(nameof(Entity.SomeListOfValues)).HasConversion(splitStringConverter);
} 

```
  Обратите внимание, что это решение не засоряет ваш бизнес-класс проблемами БД. 

 Само собой разумеется, что это решение, необходимо убедиться, что строки не могут содержать разделитель. Но, конечно, для преобразования можно использовать любую пользовательскую логику (например, преобразование из / в JSON). 

 Еще один интересный факт заключается в том, что нулевые значения *не* передаются в процедуру преобразования, а обрабатываются самой платформой. Таким образом, не нужно беспокоиться о нулевых проверках внутри процедуры преобразования. Однако все свойство становится `null` если база данных содержит значение `NULL` .