При выполнении этих запросов ваши узкие места производительности обычно попадают в одну из двух категорий:
- Получение слишком большого количества данных, которые вам не нужны.
- Слишком много обращений к базе данных.
Ваш первый пример может пострадать от первого из них. Если вы посмотрите на данные, которые возвращаются из базы данных, все данные для проекта будут повторяться для каждой связанной с ним задачи. Если с вашим проектом связано много данных, это может привести к большим накладным расходам. Если оно довольно скудное, оно не будет стоить намного дороже.
Ваш второй пример создает второе круговое путешествие для получения заданий. Дополнительное двустороннее взаимодействие вносит дополнительные издержки, но это означает, что в целом будет возвращено меньше дублированных данных. Одна дополнительная поездка туда и обратно, вероятно, не имеет большого значения, но если вы делаете это для нескольких проектов, вы можете легко получить десятки ненужных поездок туда и обратно.
Таким образом, решение о том, какой путь выбрать, будет действительно уравновешивающим, основываясь на том, как обычно выглядят ваши данные и чего вы действительно от них хотите. В этом конкретном случае вам лучше использовать:
count = db.Tasks.Count(t => t.AssignedTo.Id == db.Members.FirstOrDefault().Id)
..., который создаст один оптимизированный запрос, который просто возвращает счетчик, без лишних данных или дополнительных циклов. Таким образом, вы можете видеть, как ответ на подобные вопросы будет зависеть от того, что именно вы пытаетесь получить из базы данных.
Ответ на комментарий
Если вы пытаетесь получить все задачи, связанные с чем-то, ваш запрос должен содержать только задачи. Есть много способов сделать это:
var memberTasks = db.Tasks.Where(t => t.AssignedTo.Id == memberId).ToList();
или (если вы еще не знаете ID участника):
var memberTasks = db.Tasks.Where(t => t.AssignedTo.[your criterion]))
.ToList();
или (если вы хотите, чтобы задачи выполнялись сразу для нескольких участников):
var tasksByMemberId = (from t in db.Tasks
where t.AssignedTo.[your criterion])
select new {MemberId = t.AssignedTo.Id, t})
.ToLookup(e => e.MemberId, e => e.t);
Я мог бы продолжить. Дело в том, что все эти запросы специально выполняют задачи, не беспокоясь о данных участника.
Добавление дополнительного слоя данных тоже ничего не должно изменить:
var projectTasks = db.Tasks.Where(t => t.Iteration.Project.Id == projectId).ToList();