Как вы сопоставляете строки в базе данных с перечислениями в вашей модели, не вводя второго свойства? - PullRequest
0 голосов
/ 16 апреля 2019

В моей базе данных есть таблица, подобная этой:

Кошки

- CatId INT PK
- Name VARCHAR(100)
- FavoriteToy VARCHAR(100)

И мой код выглядит так:

Cat.cs

public int CatId { get; set; }
public string Name { get; set; }
public Toy FavoriteToy {get; set; }

StaticVariables.cs

public enum Toy { Box, Ball, StuffedAnimal }

В нормализованной базе данных я использовал бы таблицу поиска в базе данных для хранения всех игрушек, а затем таблица Cats просто сохранит ToyId. Но в этой ситуации гораздо проще просто сохранить FavoriteToy в виде строки, даже если она будет избыточной.

Проблема в том, что я не знаю, как преобразовать строку в базе данных в перечисление в коде, не создавая второе свойство FavoriteToyString и имея FavoriteToy просто вычисляемое значение, которое возвращает перечисление, полученное из FavoriteToyString .

Я слышал, что это возможно в текущей версии платформы сущностей. Это правда? Подскажите, пожалуйста, как это сделать?

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Как правило, да, справочная таблица поиска является лучшим вариантом, поскольку ваши данные могут соответствовать ссылочной целостности.То есть, никаких кошачьих записей с игрушками, которых, надеюсь, не будет в вашем Enum.(Хотя ваш Enum должен быть синхронизирован с таблицей Toys.) Вы можете настроить EF для хранения перечислений в виде строки, используя небольшую хитрость с отображением:

public class Cat
{
  [Key]
  public int CatId { get; set; }
  public string Name { get; set; }

  [Column("FavoriteToy")]
  public string FavoriteToyMapped { get; set; }

  [NotMapped]
  public Toy FavoriteToy 
  {
    get { return (Toy)Enum.Parse(typeof(Toy), FavoriteToyMapped); }
    set { FavoriteToyMapped = value.ToString(); }
  }
}

Предостережение этогоПодход заключается в том, что, когда вы можете использовать Linq to Entity для фильтрации любимой игрушки вашей кошки, вам нужно ссылаться на значение FavoriteToyMapped в выражении запроса, потому что EF / DB не будет знать, что такое FavoriteToy.

Т.е. Кошки слюбимая игрушка "Пряжи"

var catsThatLoveYarn = context.Cats.Where(c => c.FavoriteToyMapped == Toys.Yarn.ToString()).ToList();
// not
var catsThatLoveYarn = context.Cats.Where(c => c.FavoriteToy == Toys.Yarn).ToList();
// Will error because EF doesn't map that property.

После того, как вы работаете с экземплярами сущностей, этот набор сущностей был извлечен из базы данных, вы можете дополнительно получать доступ / уточнять запросы с помощью FavoriteToy.Просто будьте осторожны и будьте готовы к неизвестному полю, если вы используете его слишком рано, и EF идет и пытается составить запрос.

var threeYearOldCats = context.Cats.Where(c => c.Age == 3).ToList();
var threeYearOldCatsThatLoveYarn = threeYearOldCats.Where(c => c.FavoriteToy == Toys.Yarn).ToList();

Это нормально, потому что .ToList () в первом запросе выполнил EF-to-SQL, поэтому threeYearOldCats теперь является локальным List<Cat> объектами cat, а не IQueryable<Cat>.

0 голосов
/ 16 апреля 2019

Вы можете использовать класс DTO и automapper для решения вашей проблемы:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...