改进linq调用以进行一次db调用

时间:2012-03-24 20:57:04

标签: c# linq linq-to-sql

我可以帮助改善这个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 个答案:

答案 0 :(得分:1)

你为什么还要打第二个电话?你应该能够做到:

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

答案 1 :(得分:1)

在不知道您正在使用哪种LINQ提供程序(例如,默认的LINQ To SQL或对象关系映射程序,如Mindscape LightspeedNHibernate)或有关数据库模式的信息的情况下,很难给出任何建议。

因此,在知道之前,我能做的最好的事情是重新安排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进行搜索也是如此。
  • 将所有最近的视频作为数组查找,以便我们在下一部分中不会多次枚举该集合。
  • 对所有发言者进行迭代,并检查该发言者是否有最近的视频。
  • 然后,如果需要,请按显示名称订购扬声器。

希望这会有所帮助。如有任何问题请咨询。