Note that there are some explanatory texts on larger screens.

plurals
  1. POLINQ-SQL reuse - CompiledQuery.Compile
    primarykey
    data
    text
    <p>I have been playing about with LINQ-SQL, trying to get re-usable chunks of expressions that I can hot plug into other queries. So, I started with something like this:</p> <pre><code>Func&lt;TaskFile, double&gt; TimeSpent = (t =&gt; t.TimeEntries.Sum(te =&gt; (te.DateEnded - te.DateStarted).TotalHours)); </code></pre> <p>Then, we can use the above in a LINQ query like the below (LINQPad example):</p> <pre><code>TaskFiles.Select(t =&gt; new { t.TaskId, TimeSpent = TimeSpent(t), }) </code></pre> <p>This produces the expected output, <em>except, a query per row is generated for the plugged expression</em>. This is visible within LINQPad. Not good.</p> <p>Anyway, I noticed the <code>CompiledQuery.Compile</code> method. Although this takes a <code>DataContext</code> as a parameter, I thought I would include ignore it, and try the same <code>Func</code>. So I ended up with the following:</p> <pre><code>static Func&lt;UserQuery, TaskFile, double&gt; TimeSpent = CompiledQuery.Compile&lt;UserQuery, TaskFile, double&gt;( (UserQuery db, TaskFile t) =&gt; t.TimeEntries.Sum(te =&gt; (te.DateEnded - te.DateStarted).TotalHours)); </code></pre> <p>Notice here, that I am not using the <code>db</code> parameter. However, now when we use this updated parameter, only <strong>1</strong> SQL query is generated. The Expression is successfully translated to SQL and included within the original query.</p> <p>So my ultimate question is, what makes <code>CompiledQuery.Compile</code> so special? It seems that the <code>DataContext</code> parameter isn't needed at all, and at this point i am thinking it is more a convenience parameter to generate full queries.</p> <p>Would it be considered a good idea to use the <code>CompiledQuery.Compile</code> method like this? It seems like a big hack, but it seems like the only viable route for LINQ re-use.</p> <p><strong>UPDATE</strong></p> <p>Using the first <code>Func</code> within a <code>Where</code> statment, we see the following exception as below:</p> <pre><code>NotSupportedException: Method 'System.Object DynamicInvoke(System.Object[])' has no supported translation to SQL. </code></pre> <p>Like the following:</p> <pre><code>.Where(t =&gt; TimeSpent(t) &gt; 2) </code></pre> <p>However, when we use the <code>Func</code> generated by <code>CompiledQuery.Compile</code>, the query is successfully executed and the correct SQL is generated.</p> <p>I know this is not the ideal way to re-use <code>Where</code> statements, but it shows a little how the Expression Tree is generated.</p>
    singulars
    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.
 

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