Одна из более медленных частей запроса к базе данных - это передача выбранных данных из вашего запроса управления базой данных в локальный процесс.Следовательно, целесообразно выбирать только те значения, которые вы действительно планируете использовать.
Например, каждый PhotoPlace
имеет ноль или более ParkingLocations
, каждый ParkingLocaction
принадлежит ровно одному PhotoPlace
, используяиностранный ключ.Довольно прямое отношение «один ко многим».
Так что если у PhotoPlace 4 есть 1000 ParkingLocations, то у каждого ParkingLocation будет внешний ключ к PhotoPlace, к которому он принадлежит.Как и ожидалось, значение этого внешнего ключа будет равно 4.
Когда вы используете Include
для извлечения PhotoPlaces с помощью ParkingLocations, вы также выбираете внешние ключи.Какая трата посылать в 1000 раз больше значения 4, хотя вы уже знаете это значение.
При использовании структуры сущностей всегда используйте Select вместо Include.Используйте «Включить» только в том случае, если вы планируете обновить извлеченные данные.
Следующий запрос будет гораздо более эффективным, поскольку он только выбирает свойства, которые вы фактически планируете использовать:
var photoPlacesFound = db.PhotoPlaces
.Where(photoPlace => ...) // if you don't want all PhotoPlaces
.Select(photoPlace => new
{
// Select only the PhotoPlace properties you actually plan to use:
Id = photoPlace.Id,
...
ParkingLocations = PhotoPlace.ParkingLocations
.Select(parkingLocation => new
{
// again: select only the ParkingLocation properties you plan to use
Id = parkingLocation.Id,
Name = parkingLocation.Name,
// not needed: you already know the value:
// PhotoPlaceId = parkingLocation.PhotoPlaceId, // foreign key
ShootingLocations = parkingLocations.ShootingLocations
.Select(shootingLocation => new
{
// you know the drill by now: only select the ...
})
.ToList(),
})
.ToList(),
});
Некоторые улучшения
Я заметил, что вы объявили свои отношения один-ко-многим как списки вместо ICollections.Вы уверены, что PhotoPlace.ParkingLocation [4] имеет правильное значение?
Я также заметил, что вы не объявляли виртуальные отношения между таблицами
В платформе сущностейне виртуальные свойства представляют столбцы таблиц.Отношения между таблицами (один-ко-многим, многие-ко-многим, ...) представлены виртуальными свойствами.
До тех пор, пока вы сначала будете следовать коду структуры сущностей условные обозначения , вам не понадобятся атрибуты или свободный API для большинства элементов, что делает ваш код компактным и легким для чтения:
public class PhotoPlace
{
public long Id { get; set; }
... // other properties
// every PhotoPlace has zero or more ParkingLocations (one-to-many)
public virtual ICollection<ParkingLocation> ParkingLocations { get; set; }
}
public class ParkingLocation
{
public long Id {get; set;}
...
// every ParkingLocation belongs to exactly one PhotoPlace using foreign key
public long PhotoPlaceId {get; set;}
public virtual PhotoPlace PhotoPlace {get; set;}
// every ParkingLocation has zero or more ShootingLocations (one-to-many)
public virtual ICollection<ShootingLocation> ShootingLocations {get; set;}
}
Поскольку я следовал соглашениям, ModelBuilder способен обнаруживатьназвания таблиц и столбцов.Он может обнаружить первичные ключи.Из-за виртуального ключевого слова ему известно отношение между таблицами и внешними ключами, используемыми в этих отношениях.
Поскольку я использую ICollection <...>, ваш компилятор не примет неопределенную функциональность, такую как List [4]
Наконец: поскольку конструкторы ничего не делают, я их удалил