改进linq调用,使之成为一个db调用

本文关键字:调用 一个 db linq 改进 | 更新日期: 2023-09-27 18:28:50

我能帮我改进这个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;
    }

改进linq调用,使之成为一个db调用

为什么要进行第二次调用?你应该能够做到:

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;
}

如果不知道您正在使用什么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);
}
  • 让扬声器无序排列,尽可能晚些时候执行排序。如果排序是为了演示,请稍后在视图中执行
  • 存储上周的日期。我使用DateTime.Now.Datex.DataPosted.Date,这样我们就不会比较时间,也就是说,即使你在晚上11:59搜索,你也希望找到上周以来的所有视频
  • 将所有最近的视频作为一个数组查找,这样我们就不会在下一部分中多次枚举该集合
  • 遍历所有扬声器,并检查该扬声器是否有任何最近的视频
  • 然后,如果需要,按显示器名称对扬声器进行排序