我一次从所有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!!
答案 0 :(得分:1)
你在foreach循环中使用IEnumerable
。实现只需要在需要时准备数据。通过这种方式,我建议上面的代码懒洋洋地访问你的数据 - 也就是说,只有当你枚举这些项目时(实际上当你调用Count()
时才会这样。)
在System.Diagnostics.Stopwatch
的电话周围加Count()
,看看是否占用了大部分时间。
我无法在此进一步发表评论,因为您未在代码示例中指定ent
的类型。
答案 1 :(得分:1)
为什么在foreach陈述之前打扰检查计数?如果没有结果,foreach将立即完成。
您的查询实际上都被延期 - 它们将在您要求提供数据时执行。不要忘记你的最外层查询是一个LINQ to Objects查询:它只返回调用ent.Basket.Where(...).Select(...)
等的结果......它实际上并不执行查询。
您一次性完成所有三个查询的计划实际上并不起作用。但是,通过单独请求计数,您实际上可能正在执行两次数据库查询 - 一次只是计数,一次是结果。
我强烈建议你摆脱这段代码中的“优化”,这使得它变得更复杂,而且更慢,而不仅仅是编写最简单的代码。
我不知道如何让LINQ to SQL(或LINQ to EF)在一次调用中执行多个查询 - 但这种方法肯定不会这样做。
另一个小提示在这种情况下是无关紧要的,但在LINQ to Objects中很有用 - 如果你想知道集合中是否有任何数据,只需使用Any()
而不是{{1} - 这样一旦找到任何东西就可以停止。