улучшить вызов linq, чтобы сделать один вызов БД - PullRequest
0 голосов
/ 25 марта 2012

Могу ли я помочь с улучшением этого linq.Я в основном возвращаю спикеров из базы данных, но присваиваю свойству HasNew значение true, если они были опубликованы на прошлой неделе.

   public IQueryable<Speaker> GetSpeakers()
    {
        var speakers =  db.Speakers.OrderBy(x => x.DisplayName);
        var newVidsSpeakers = db.Videos.Where(x => x.DatePosted > DateTime.Now.AddDays(-7)).Select(x=> x.Speaker).Distinct();
        foreach (var item in newVidsSpeakers)
        {
            var sp = speakers.SingleOrDefault(x => x.ID == item.ID);
            sp.HasNew = true;
        }
        return speakers;
    }

Ответы [ 2 ]

1 голос
/ 25 марта 2012

Не зная, какой поставщик LINQ вы используете (например, используемый по умолчанию LINQ To SQL или объектный реляционный маппер, такой как Mindscape Lightspeed или NHibernate ) или информацию о схеме базы данных, это сложнодать любой совет.

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

Примечание: Вы можете обнаружить, что невозможно сократить это до одного вызова базы данных.

Вот как бы я написал подобный запрос.

public IEnumerable<Speaker> GetSpeakers()
{
    var speakers = db.Speakers;
    var lastWeek = DateTime.Now.Date.AddDays(-7);
    var recentVideos = db.Videos.Where(x => (x.DatePosted.Date >= lastWeek)).ToArray();

    foreach (var speaker in speakers)
        speaker.HasNew = recentVideos.Any(x => (x.Speaker == speaker));

    return speakers.OrderBy(x => x.DisplayName);
}
  • Получите неупорядоченные колонки, так как выполняйте заказ как можно позже.Если заказ предназначен для презентации, сделайте это позже в представлении.
  • Сохраните дату 1024 * на прошлой неделе.Я использую DateTime.Now.Date и x.DataPosted.Date, чтобы мы не сравнивали время, т.е. вы хотите найти все видео с прошлой недели, даже если вы выполняете поиск в 23:59.
  • Найти все последние видеокак массив, чтобы мы не перечисляли коллекцию несколько раз в следующей части.
  • Переберите все динамики и проверьте, есть ли на этом динамике последние видео.
  • Затем, если необходимо, упорядочите динамики по отображаемому имени.

Надеюсь, это поможет.Любые вопросы, пожалуйста, задавайте.

1 голос
/ 25 марта 2012

Почему вы все равно делаете второй звонок? Вы должны просто быть в состоянии сделать:

public IQueryable<Speaker> GetSpeakers()
{
    var speakers = db.Speakers.OrderBy(x => x.DisplayName);
    var newVidsSpeakers = db.Videos.Where(x => x.DatePosted > DateTime.Now.AddDays(-7)).Select(x => x.Speaker).Distinct();
    foreach (var speaker in newVidsSpeakers)
    {
        speaker.HasNew = true;
    }
    return speakers;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...