title: How can I build Entity Framework queries dynamically?
body: <p>I'm quite new to Entity Framework and I have a question about filtering data.</p>
  
  <p>I have two various Log entities, they are: <code>DiskLog</code> and <code>NetworkLog</code>. These entities both are derived from <code>Log</code> entity. Here is some code from my C# app:</p>
  
  <pre><code>public class Log { ... }
  public class DiskLog : Log { ... }
  public class NetworkLog : Log { ... }
  
  public enum LogType
  {
      NotInitialized = 0,
      Disk,
      Network
  }
  
  public List&lt;Log&gt; GetWithFilter(
      Guid userKey, 
      int nSkip, 
      int nTake, 
      DateTime dateFrom = DateTime.MinValue, 
      DateTime dateTo = DateTime.MaxValue, 
      LogType logType = LogType.NotInitialized, 
      int computerId = 0)
  {
      // need to know how to optimize ...
  
      return ...
  }
  </code></pre>
  
  <p>Of course, I already have working app and database tables created. What I want to do is to make function GetWithFilter work. I have several execution ways there:</p>
  
  <ol>
  <li><p><code>if logType == LogType.Disk &amp;&amp; computerId &lt;= 0</code> (it means there is no need to use computerId parameter in the query, select DiskLog entities only)</p></li>
  <li><p><code>if logType == LogType.Disk &amp;&amp; computerId &gt; 0</code> (means I have to use computerId parameter, select DiskLog entities only)</p></li>
  <li><p><code>if logType == LogType.NotInitialized &amp;&amp; computerId &lt;= 0</code> (no need to use computerId and logType, just select all the entities, DiskLog and NetworkLog)</p></li>
  <li><p><code>if logType == LogType.NotInitialized &amp;&amp; computerId &gt; 0</code> (select all types of logs for specified computer)</p></li>
  <li><p><code>if logType == LogType.Network &amp;&amp; computerId &lt;= 0</code> (select all NetworkLog entities)</p></li>
  <li><p><code>if logType == LogType.Network &amp;&amp; computerId &gt; 0</code> (select all NetworkLog entities for specified computer)</p></li>
  </ol>
  
  <p>As you can see, there are plenty of available options. And I got to write 6 queries like this:</p>
  
  <p>1.</p>
  
  <pre><code>context.LogSet
      .OfType&lt;DiskLog&gt;
      .Where(x =&gt; x.Computer.User.UserKey == userKey)
      .Where(x =&gt; x.DateStamp &gt;= dateFrom &amp;&amp; x.DateStamp &lt; dateTo)
      .OrderByDescending(x =&gt; x.Id)
      .Skip(nSkip)
      .Take(nTake)
      .ToList();
  </code></pre>
  
  <p>2.</p>
  
  <pre><code>context.LogSet
      .OfType&lt;DiskLog&gt;
      .Where(x =&gt; x.Computer.User.UserKey == userKey)
      .Where(x =&gt; x.DateStamp &gt;= dateFrom &amp;&amp; x.DateStamp &lt; dateTo)
      .Where(x =&gt; x.Computer.Id == computerId)
      .OrderByDescending(x =&gt; x.Id)
      .Skip(nSkip)
      .Take(nTake)
      .ToList();
  </code></pre>
  
  <p>3.</p>
  
  <pre><code>context.LogSet
      .Where(x =&gt; x.Computer.User.UserKey == userKey)
      .Where(x =&gt; x.DateStamp &gt;= dateFrom &amp;&amp; x.DateStamp &lt; dateTo)
      .OrderByDescending(x =&gt; x.Id)
      .Skip(nSkip)
      .Take(nTake)
      .ToList(); // simplest one!
  </code></pre>
  
  <p>4.</p>
  
  <pre><code>context.LogSet
      .Where(x =&gt; x.Computer.User.UserKey == userKey)
      .Where(x =&gt; x.DateStamp &gt;= dateFrom &amp;&amp; x.DateStamp &lt; dateTo)
      .Where( x =&gt; x.Computer.Id == computerId)
      .OrderByDescending(x =&gt; x.Id)
      .Skip(nSkip)
      .Take(nTake)
      .ToList();
  </code></pre>
  
  <p>5.</p>
  
  <pre><code>context.LogSet
      .OfType&lt;NetworkLog&gt;
      .Where(x =&gt; x.Computer.User.UserKey == userKey)
      .Where(x =&gt; x.DateStamp &gt;= dateFrom &amp;&amp; x.DateStamp &lt; dateTo)
      .OrderByDescending(x =&gt; x.Id)
      .Skip(nSkip)
      .Take(nTake)
      .ToList();
  </code></pre>
  
  <p>6.</p>
  
  <pre><code>context.LogSet
      .OfType&lt;NetworkLog&gt;
      .Where(x =&gt; x.Computer.User.UserKey == userKey)
      .Where(x =&gt; x.DateStamp &gt;= dateFrom &amp;&amp; x.DateStamp &lt; dateTo)
      .Where( x =&gt; x.Computer.Id == computerId)
      .OrderByDescending(x =&gt; x.Id)
      .Skip(nSkip)
      .Take(nTake)
      .ToList();
  </code></pre>
  
  <p>So the question is how can I optimize the code? Where is the way to make it better.</p>