Я вижу несколько возможных улучшений.
По какой-то причине вы решили отклониться от соглашений по коду структуры сущностей .Одним из них является использование List
вместо ICollection
, другое - исключение упоминания внешних ключей.
Использование ICollection вместо List
Вы уверены, что Ticket.TicketFiles[4]
имеет определенное значение?А что бы значило Ticket.TicketFiles.Insert(4, new TicketFile())
Лучше придерживаться интерфейса, который запрещает использование функций, которые не имеют определенного значения.Используйте ICollection<TicketFile>
.Таким образом, вы будете иметь только те функции, которые имеют правильное значение в контексте базы данных.Кроме того, он дает инфраструктуре сущностей свободу выбора наиболее эффективного типа коллекции для выполнения своих запросов.
Пусть ваши классы представляют таблицы
Пусть ваши классы просто являются POCO.Не добавляйте никаких функций, которых нет в ваших таблицах.
В каркасе сущностей столбцы таблицы представлены не виртуальными свойствами.Виртуальные свойства представляют отношения между таблицами (один-ко-многим, многие-ко-многим, ...)
Пусть структура сущностей решает, что наиболее эффективно для инициализации данных в ваших последовательностях,Не используйте конструктор, в котором вы создаете List, который будет немедленно отброшен структурой сущностей, чтобы заменить его собственным ICollection
.Не инициализируйте автоматически свойство Deleted
, если платформа сущностей немедленно заменит его своим собственным значением.
Вероятно, у вас будет только одна процедура, в которой вы добавите билет в базу данных.Используйте эту функцию для правильной инициализации поля любого «вновь добавленного тикета»
Не забудьте внешние ключи
Вы определили несколько отношений между вашими таблицами (одно-to-many или many-to-many?) но вы забыли определить внешние ключи.Поскольку вы используете virtual
, сущностный каркас может понять, что ему нужны внешние ключи, и он их добавит, но в вашем запросе вам нужно написать e.Status != null && e.Status.Id == statusId
, тогда как, очевидно, вы можете просто использовать внешний ключ e.StatusId == statusId
.Для этого вам не нужно объединяться с таблицей «Статусы»
Еще одна причина указать внешние ключи: они являются реальными столбцами в ваших таблицах.Если вы определите, что эти классы представляют ваши таблицы, они должны быть в этих классах!
Выберите только те свойства, которые вы действительно планируете использовать
Одна из более медленных частейзапрос к базе данных - это передача выбранных данных из системы управления базами данных в локальный процесс.Следовательно, разумно выбирать только те данные, которые вы действительно планируете использовать.
Пример.Кажется, между User
и Ticket
существует отношение один ко многим: каждый пользователь имеет ноль или более Tickets
, каждый Ticket
принадлежит ровно одному User
.Предположим, что User
4 имеет 20 Tickets
.Каждый Ticket
будет иметь UserId
со значением 4. Если вы получите эти 20 Tickets
без правильного Select
, вы получите все свойства одного и того же User
4 один раз за Ticket
, и вы получитетранспортировать данные этого же User
20 раз (со всеми его свойствами и, возможно, всеми его отношениями).Какая трата вычислительной мощности!
Всегда использовать Select для запроса ваших данных и Select только те свойства, которые вы фактически планируете использовать.Используйте функцию «Включить» только в том случае, если вы планируете обновить включенные данные.
var tickets = dbContext.Tickets.Where(ticket => !ticket.Deleted
// improvement: use foreign keys
&& ticket.ProjectId == 0 (or == null, if ProjectId nullable)
&& ticket.StatusId == statusId) // no Join with Statuses needed
.Select(ticket => new
{
...
}