2013-03-29 108 views
-1

我有以下LINQ查询:LINQ到数据集,查询优化

var itembind = (from q in dsSerach.Tables[0].AsEnumerable() 
      select new 
          { 
           PatternID = q.Field<int>("PatternID"), 
           PatternName = q.Field<string>("PatternName") + " " + q.Field<string>("ColorID") + q.Field<string>("BookID"), 
           ColorID = q.Field<string>("ColorID"), 
           BookID = q.Field<string>("BookID"), 
           CoverImage = (from img1 in objJFEntities.ProductImages.ToList() 
              where img1.PatternName.ToLower() == q.Field<string>("PatternName").ToLower() 
              select new CoverImage 
              { 
               URL = "Images/MediumPatternImages/" + 
                q.Field<string>("PatternName") + "_" + q.Field<string>("ColorID") + q.Field<string>("BookID") + q.Field<string>("ImageExtension"), 
               ID = q.Field<int>("ProductImageID") 
              }).FirstOrDefault(), 
           TotalCount = q.Field<int>("TotalCount") 
          }).Distinct(); 



var patterns = (from r in itembind 
      group r by new { r.PatternID, r.ColorID } into g 
      select new SearchPattern 
      { 
       PatternID = g.Key.PatternID, 
       PatternName = string.Join(",", g.OrderBy(s => s.ColorID).OrderBy(s => s.BookID) 
              .Select(s => String.Format("<a href='{0:s}' title='{1:s}'>{2:s}</a><br />", 
                new object[] { String.Format("Product.aspx?ID={0}&img={1}", g.Key.PatternID, s.CoverImage.ID), s.PatternName, s.PatternName })).FirstOrDefault()), 
       CoverImage = g.Count() > 1 ? (from img1 in objJFEntities.ProductImages.ToList() 
               where img1.ProductImageID == g.Select(i => i.CoverImage.ID).FirstOrDefault() && img1.ColorID.ToString() == g.Key.ColorID 

               select new CoverImage 
               { 
                URL = "Images/MediumPatternImages/" + 
                 img1.PatternName + "_" + img1.ColorID + img1.BookID + img1.ImageExtension, 
                ID = img1.ProductImageID 
               }).FirstOrDefault() : g.Select(i => i.CoverImage).FirstOrDefault() 


      }).ToList(); 

这些查询正在采取更多然后1分钟到执行只为1000条记录。 dsSearch是一个数据集,填充了SQL中从我的过程返回的记录。 我正在使用实体框架。该网站使用IIS7.0进行部署。 SQL Server 2008正在使用中。

我“错误消息:超时过期之前,操作完成或服务器没有响应超时时间已过。” 通过登录“无法打开数据库‘DB’请登录失败。 “。 &“底层提供程序在打开时失败。”这种错误非常频繁的网站。

请告诉我如何优化这样的查询。

编辑:

下面是该过程

http://pastie.org/7160934

+0

您确认您的连接字符串是正确的吗?你在使用集成安全吗? –

+0

是的,我验证了这一点。在连接字符串 – Neha

+0

我不使用集成安全性的错误当然意味着其对数据库超时,而不是查询的连接(我觉得默认的超时时间为60秒)。我会检查连接和你的IIS设置。 –

回答

2

Rolfvm是指出objJFEntities.ProductImages引起该问题是正确的,但分析是一个有点不同。您获取整个ProductImages表到内存每个迭代查询,当您枚举它。所以一个优化将是一个集合中的第一获取图像,并使用集合中的查询语句

var localImages = objJFEntities.ProductImages.ToList(); 
... 
CoverImage = (from img1 in localImages.... 

不过,您的查询似乎做太多。您在不执行它的情况下构建第一部分itembind。然后,你建立的第二部分(var patterns = (from r in itembind)和ToList()执行它。但在第二部分中,您从不使用第一部分中的CoverImage。所以创建这些是浪费资源。 (或者你删除了代码,隐藏了第一部分的另一个用法)。

+0

谢谢,推动收集分开作品,它现在需要以前的1/4的时间。我明白不同,非常感谢。请一次验证我的程序,如果可以优化,也给我一个建议。 – Neha

+0

好吧,正如我所说的,我想知道为什么要创建'CoverImage'对象。你可以尝试只抓取你需要的'ProductImages'。 –

+0

coverImage用于模式查询以及我的用户界面中的结果 – Neha

3

在第一个查询你正在做一个objJFEntities.ProductImages.ToList(),与ToList()调用你取来自数据库的每个条目,然后在内存中过滤结果。

+0

我尝试删除ToList()后。之后查询将不会提供任何输出。 – Neha

+0

但我敢打赌,查询的性能好得多;)。 – Rolfvm

+0

但ToLower将()动作propably不会被映射到SQL的支持(不知道哪个DB您正在使用)。所以这取决于您使用的数据库合并。 最好的事情,看看为什么你的查询没有返回任何结果是使用包含在SQL Management Studio中 – Rolfvm