-1

我有以下 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();

这些查询仅对 1000 条记录执行超过 1 分钟。dsSearch 是一个数据集,其中填充了从我的 SQL 过程返回的记录。我正在使用实体框架。该站点使用 IIS7.0 部署。SQL Server 2008 正在使用中。

我收到“错误消息:超时已过期。在操作完成之前超时时间已过或服务器没有响应。 ”,“无法打开登录请求的数据库“DB”。登录失败。” &“基础提供商在打开时失败。” 那种错误非常频繁的网站。

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

编辑:

这是程序

http://pastie.org/7160934

4

2 回答 2

3

在第一个查询中,您正在执行 objJFEntities.ProductImages.ToList() ,通过 ToList() 调用,您将从数据库中获取每个条目,然后在内存中过滤结果。

于 2013-03-29T12:46:48.690 回答
2

Rolfvm 指出objJFEntities.ProductImages导致问题的原因是正确的,但分析有点不同。当您枚举查询时,您会将整个ProductImages表提取到内存中以进行查询的每次迭代。因此,一种优化是首先在集合中获取图像并在查询语句中使用该集合

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

但是,您的查询似乎做得太多了。您构建第一部分itembind而不执行它。然后构建第二部分 ( var patterns = (from r in itembind) 并通过ToList(). 但是在第二部分中,您永远不会使用CoverImage第一部分中的。所以创造这些是对资源的浪费。(或者你浏览了代码,隐藏了第一部分的另一个用途)。

于 2013-03-29T20:37:43.033 回答