我有两个长查询,每个类型都是“typeViewRequest”
results1 = ..... (timeout)
results2=..... (timeout)
现在.....
案例1 --------------------------------------------- --------------------------------
如果我这样做
results1 = ..... .Take(countRecordsToShow/2)
results2 = ..... .Take(countRecordsToShow/2)
然后我说
results = results1.Union<typeViewRequest>(results2);
它工作正常。使用分页的网格显示了countRecordsToShow记录,这里没问题。
案例2 --------------------------------------------- --------------------------------
如果我这样做
results1 = .....
results2 = .....
然后我说
results = results1.Union<typeViewRequest>(results2).Take(countRecordsToShow)
然后我有一个超时。为什么?因为我的gridview显然需要获取记录数,才能设置其分页。我的SelectCountMethod,名为getPreviousRequestsSelectCount,只是说
public int getPreviousRequestsCountFromDB(String name, DateTime dtStart, DateTime dtEnd, ReportedBy_Filter reportedBy, Status_Filter status, ReportType_Filter type, int countRecordsToShow, int userID)
{
return getPreviousRequests(companyNameLike: name, dtStart: dtStart, dtEnd: dtEnd, reportedBy: reportedBy, status: status, type: type, sortExpression: null, userID: userID, countRecordsToShow: countRecordsToShow).Count();
}
在get1reviousRequests内部,在Case1中,应用了TAKE(如“案例2”中所述):
results = results1.Union<typeViewRequest>(results2).Take(countRecordsToShow)
虽然countRecordsToShow只有20,但它超时了!我缓存那个数字,直到过滤标准改变,是的,但仍然......: - ((
其他问题:我也有一些过滤要做。这种过滤应该在BOTH分支上进行,如下所示:
results1 = ..... Where (something1)
results2 = ..... .Where (something2)
但如果我说,就像案例1一样,
results1 = ..... Where (something1).Take(countRecordsToShow/2)
results2 = ..... .Where (something2).Take(countRecordsToShow/2)
这会切断我的过滤数据集,我担心 - 让我们说countRecordsToShow = 20.如果results1(由something1过滤)有15条记录,我只需要10.如果results2(由something2过滤)比方说,5条记录,我会拿5.然后UNION将有15条而不是20条记录。
通常我应该这样做,就像在Case2中一样:
results1 = ..... Where (something1)
results2 = ..... .Where (something2)
然后说
results = results1.Union<typeViewRequest>(results2).Take(countRecordsToShow)
如果过滤的results1.Union(results2)有25条记录但countRecordsToShow为20,那么就这样吧。我只想说数据集不完整,需要额外的过滤。
但是因为我必须在UNION之前修剪数据集,否则这会影响我的过滤!
我预计结果查询将首先拉出每个分支,然后执行UNION,然后过滤,然后在最后修剪。
好吧,显然如果我在做其他事情之前没有修剪每个分支,我会暂停。
这一切如何运作?我非常困惑。我甚至无法使用COUNT来查找我应该期望的记录数,并且因此表现得很好,因为COUNT枚举了数据集,因此给了我一个超时。
请问有什么选择? (没有创建sprocs,我不允许这样做)。现在我发现的唯一“解决方案”是case1 - 在联盟之前向每个分支应用TAKE子句,但正如我所提到的那样,在过滤方面会出错。
我在这里做错了什么?我真的需要配合“逻辑残障”案例1吗?请帮忙!
谢谢
亚历
注意:
我测试了这个:如果执行了行
results = results1.Union<typeViewRequest>(results2).Take(20)
我试着检查
results.count()
在即时窗口中,它超时了!它没有看到它有.Take(20)条款吗?为什么首先必须枚举所有记录?我应该列举到极限,20,然后停止。显然它一直枚举到大约250.000,然后将结果集修剪为20。
注意:我在这里读到:Exploring LINQ Query Operators and Differed Execution Plan TAKE和UNION都被定义了。那么....为什么不将TAKE集成到查询中,而是应用于事后呢?
答案 0 :(得分:0)
我不能说我理解你的整个帖子,但我最近的经历可能适用于此。 。 。因为你有零帖子。 。 。我试试看。
我有这样的事情:
var results = from ... ;
foreach(results)
{
do something
}
工作得很好,但运行了四分钟,因为结果包含了400万条记录。由于我是LINQ / EF4 newb,我将其更改为:
var results = from<blah>;
int count = 0;
foreach(results)
{
if (count++ > 100)
break;
do something
}
执行此操作后,它会在第100条记录之后的foreach语句中超时并终止foreach循环。
经过多次阅读和实验后我得出的结论是查询将完成!!!
不管你喜不喜欢,Query都会运行完成。
因此,在原始格式中,我通过逐个获取每个小块来在foreach循环中运行查询。这样做永远不会超时,因为解析结果中的下一个项目非常快。
但是,一旦我输入了break语句,在第100条记录之后,查询试图在单个gulp中完成自身,因此它将超时,因为在单个调用获取的超时中无法接受400万条记录
结果即将超出范围并被销毁的事实并不重要。查询必须完成。 。 。使用与否。 。 。必须完成查询。
这是一项非常令人沮丧但又具有启发性的练习。
谢