Note that there are some explanatory texts on larger screens.

plurals
  1. POLINQ to entities execution order/timing question
    primarykey
    data
    text
    <p>I have two long queries, each of type "typeViewRequest"</p> <pre><code> results1 = ..... (timeout) results2=..... (timeout) </code></pre> <p>Now.....</p> <p>Case 1-----------------------------------------------------------------------------</p> <p>If I do</p> <pre><code> results1 = ..... .Take(countRecordsToShow/2) results2 = ..... .Take(countRecordsToShow/2) </code></pre> <p>and then I say</p> <pre><code> results = results1.Union&lt;typeViewRequest&gt;(results2); </code></pre> <p>it works fine. The grid, using paging, shows the countRecordsToShow records, no problem here.</p> <p>Case 2-----------------------------------------------------------------------------</p> <p>If I do</p> <pre><code> results1 = ..... results2 = ..... </code></pre> <p>and then I say</p> <pre><code> results = results1.Union&lt;typeViewRequest&gt;(results2).Take(countRecordsToShow) </code></pre> <p>then I have a timeout. Why ? Because my gridview, obviously, needs to get the count of records, to set its paging. My SelectCountMethod, called getPreviousRequestsSelectCount, simply says </p> <pre><code>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(); } </code></pre> <p>Inside getPreviousRequests, in Case1, TAKE is applied (as described in "case 2"):</p> <pre><code>results = results1.Union&lt;typeViewRequest&gt;(results2).Take(countRecordsToShow) </code></pre> <p>while countRecordsToShow is only 20, but it times out ! I cache that number until the filtering criteria changes, yes, but still... :-(( </p> <p>Additional problem: I also have some filtering to do. This filtering should happen on BOTH branches, like so:</p> <pre><code> results1 = ..... Where (something1) results2 = ..... .Where (something2) </code></pre> <p>but if I say, like in case 1,</p> <pre><code> results1 = ..... Where (something1).Take(countRecordsToShow/2) results2 = ..... .Where (something2).Take(countRecordsToShow/2) </code></pre> <p>this will CUT my filtered datasets, I'm afraid - let's say that countRecordsToShow = 20. If results1 (filtered by something1) had, say, 15 records, I would take only 10. If results2 (filtered by something2) had, say, 5 records, I would take 5. Then the UNION would have 15 instead of 20 records.</p> <p>Normally I should do this, like in Case2:</p> <pre><code> results1 = ..... Where (something1) results2 = ..... .Where (something2) </code></pre> <p>AND then say </p> <pre><code>results = results1.Union&lt;typeViewRequest&gt;(results2).Take(countRecordsToShow) </code></pre> <p>If the filtered results1.Union(results2) had 25 records but countRecordsToShow were 20, then so be it. I would just say that the dataset is not complete, and additional filtering is necessary.</p> <p>But since I have to trim the dataset BEFORE the UNION, this will affect my filtering BADLY !</p> <p>I expected that the resulted query will first pull each branch, then execute the UNION, then filter, and then trim, right at the end.</p> <p>Well, apparently if I don't trim each branch before doing anything else, I get a timeout.</p> <p>How does this all work ? I'm VERY confused. I cannot even use a COUNT to find out how many records I should expect, and to behave in consequence, because COUNT enumerates the dataset, thus giving me a timeout.</p> <p>What are my options, please ? (short of creating sprocs, which I am not allowed to do). Right now the only "solution" I have found is case1 - to apply a TAKE clause to each of the branches, BEFORE the Union, but, as I've mentioned, that would be wrong with regard to filtering. </p> <p>What am I doing wrong here ? Do I really need to go with the "logically handicapped" case1 ? Please help !</p> <p>Thank you</p> <p>Alex</p> <p>Note: </p> <p>I have tested this: If after executing the line</p> <pre><code>results = results1.Union&lt;typeViewRequest&gt;(results2).Take(20) </code></pre> <p>I try to check </p> <pre><code>results.count() </code></pre> <p>in the immediate window, it times out ! Does it not see that it has a .Take(20) clause ? Why does it have to enumerate ALL the records first ??? I should enumerate up to the limit, 20, and then stop. Apparently it enumerates all the way to about 250.000, and then trims the resultset to 20.</p> <p>Note: I read here: <a href="http://www.codeproject.com/KB/linq/linq_in_dept.aspx" rel="nofollow">Exploring LINQ Query Operators and Differed Execution Plan </a> that both TAKE and UNION are deffered. So then.... why is not TAKE integrated into the query, but applied AFTER the fact ?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload