0

我一次从所有 3 个表中获取数据以避免网络延迟。获取数据非常快,但是当我遍历结果时会花费大量时间

Int32[] arr = { 1 };
var query = from a in arr
            select new
            {
              Basket = from b in ent.Basket
                       where b.SUPERBASKETID == parentId
                       select new
                       {
                           Basket = b,
                           ObjectTypeId = 0, 
                           firstObjectId = "-1",
                       },

              BasketImage = from b in ent.Image
                            where b.BASKETID == parentId
                            select new
                            {
                                Image = b,
                                ObjectTypeId = 1, 
                                CheckedOutBy = b.CHECKEDOUTBY,
                                firstObjectId = b.FIRSTOBJECTID,
                                ParentBasket = (from parentBasket in ent.Basket
                                                where parentBasket.ID == b.BASKETID
                                                select parentBasket).ToList()[0],
                            },

              BasketFile = from b in ent.BasketFile
                           where b.BASKETID == parentId
                           select new
                           {
                               BasketFile = b,
                               ObjectTypeId = 2, 
                               CheckedOutBy = b.CHECKEDOUTBY,
                               firstObjectId = b.FIRSTOBJECTID,
                               ParentBasket = (from parentBasket in ent.Basket
                                               where parentBasket.ID == b.BASKETID
                                               select parentBasket),
                           }
            };

//Exception handling

var mixedElements = query.First();
ICollection<BasketItem> basketItems = new Collection<BasketItem>();

//Here 15 millis has been used
//only 6 elements were found

if (mixedElements.Basket.Count() > 0)
{
  foreach (var mixedBasket in mixedElements.Basket){}
}

if (mixedElements.BasketFile.Count() > 0)
{
  foreach (var mixedBasketFile in mixedElements.BasketFile){}
}

if (mixedElements.BasketImage.Count() > 0)
{
  foreach (var mixedBasketImage in mixedElements.BasketImage){}
}

//the empty loops takes 811 millis!!
4

2 回答 2

1

IEnumerable在 foreach 循环中使用。实现只需要在需要时准备数据。通过这种方式,我建议上面的代码懒惰地访问您的数据——也就是说,只有当您枚举项目时(这实际上发生在您调用Count().)

拨打System.Diagnostics.Stopwatch电话Count(),看看这是否占用了您所看到的大部分时间。

我不能在这里进一步评论,因为您没有ent在代码示例中指定类型。

于 2009-10-30T07:57:55.157 回答
1

你为什么要在 foreach 语句之前检查计数?如果没有结果,foreach 将立即结束。

您的查询实际上都被推迟了 - 它们将在您请求数据时执行。不要忘记您最外层的查询是一个 LINQ to Objects 查询:它只是返回调用ent.Basket.Where(...).Select(...)等的结果......实际上并没有执行查询。

您一次完成所有三个查询的计划实际上并没有奏效。但是,通过单独询问计数,您实际上可能会执行每个数据库查询两次——一次只是获取计数,一次是为了结果。

我强烈建议您摆脱此代码中的“优化”,这使得它比编写最简单的代码更加复杂和缓慢。

我不知道有任何方法可以让 LINQ to SQL(或 LINQ to EF)在一次调用中执行多个查询 - 但这种方法肯定不会这样做。

另一个在这种情况下无关紧要的小提示,但在 LINQ to Objects 中可能很有用 - 如果您想找出集合中是否有任何数据,只需使用Any()而不是Count() > 0- 这样它就可以在找到任何东西后立即停止.

于 2009-10-30T08:06:57.157 回答