При использовании структуры сущностей люди склонны (группировать) объединять таблицы самостоятельно, тогда как вместо этого гораздо проще использовать ICollections
.
Прежде всего: придерживайтесь Entity FrameworkУсловные обозначения в коде!
Например:
Каждый CarMake
имеет ноль или более CarModels
.Вы решили объявить это как List<CarModel>
.Вы уверены, что CarModel[4]
имеет определенное значение?И мне интересно, что бы означало CarModel.Insert(4, new CarModel())
в вашем коде.Лучше придерживаться интерфейса, который действительно может обрабатывать ваша база данных: ICollection<CarModel>
.
Соотношение между CarMakes
и CarModels
кажется много-многим: каждый CarMake
имеет ноль или болееCarModels
, Каждое CarModel
состоит из нуля или более CarMakes
.
В реляционных базах данных отношение «многие ко многим» реализуется с использованием таблицы соединений.Ваш класс CarsAndModel
представляет строку в этой соединительной таблице.Тем не менее, при использовании структуры сущностей вам не нужно упоминать таблицу соединений.Когда вы правильно проектируете свои классы, структура сущностей распознает отношения между вашими таблицами и создает для них правильную соединительную таблицу.
class CarMake
{
public int CarMakeId { get; set; }
public string CarMakeName { get; set; }
// every CarMake makes zero or more CarModels (many-to-many)
public virtual ICollection<CarModel> CarModels { get; set; }
}
class CarModel
{
public int CarModelId { get; set; }
public string CarModelName { get; set; }
// every CarModel is made by zero or more CarMakes (many-to-many)
public virtual ICollection<CarMake> CarMakes {get; set;}
}
В структуре сущностей столбцы таблиц представлены не виртуальнымисвойства.Виртуальные свойства представляют отношения между таблицами (один ко многим, многие ко многим, ...)
Для полноты DbContext:
class CarContext : DbContext
{
public DbSet<CarMake> CarMakes {get; set;}
public DbSet<CarModel> CarModels {get; set;}
}
Thisэто все, что должна знать структура сущностей, чтобы обнаружить отношение «многие ко многим».Entity Framework создаст для вас соединительную таблицу и будет обновлять эту таблицу по мере необходимости.
Только в том случае, если у вас есть веские причины отклоняться от соглашений, основанных на коде (и вы можете убедить своего руководителя проекта).) вам понадобятся атрибуты или свободный API для информирования структуры сущностей о ваших отклонениях.
Но как мне присоединиться к таблицам, если я не могу получить доступ к соединительной таблице?
Ответ: не делайте (групповое) объединение, используйте ICollections!
Требование: дайте мне CarModels, каждая со своими CarMakes
var result = dbContext.CarModels
.Where(carModel => ...) // only if you don't want all CarModels
.Select(carModel => new
{
// Select only the properties you actually plan to use!
Id = carModel.CarModelId,
Name = carModel.CarModelName,
...
CarMakes = carModel.CarMakes
.Where(carMake => ...) // only if you don't want all CarMakes of this model
.Select(carMake => new
{
// again: select only the properties you plan to use
Id = carMake.CarMakeId,
Name = carMake.Name,
...
})
.ToList(),
}
Entity Framework знает ваше отношение «многие ко многим» и создаст для вас правильное (групповое) соединение.