title: RavenDB IEnumerable vs List
body: <p>I have some behavior that I don't understand. I'm using RavenDB, and I'm using a session for each unit of work: When a logic class calls the RavenDB data access layer (DAL), a new session is created. Within the DAL, other DAL classes and methods can be invoked, but just one session will be used.</p>
  
  <p>The part I don't understand is the difference between using IEnumerable and List within the GetMostRecentByStartTime() method below. In that method, using List just like what's shown, this is my output:</p>
  
  <p>Using List:<br>
  Number of requests just before closing session: 2<br>
  Number of requests just before closing session: 4<br>
  Number of requests just before closing session: 6<br>
  Number of requests just before closing session: 7<br></p>
  
  <p>Note: The session doesn't actually get closed each of these times; only after the last time. We only close the session when the originally-called DAL method is done.</p>
  
  <p>Now, if I replace every instance of List with IEnumerable (and that's the <em>only</em> change I make), I get this output:</p>
  
  <p>Using IEnumerable:<br>
  Number of requests just before closing session: 2<br>
  Number of requests just before closing session: 3<br>
  Number of requests just before closing session: 4<br>
  Number of requests just before closing session: 27<br></p>
  
  <p>Why the difference?</p>
  
  <p>Another issue is that the request count increases, using the IEnumerable approach, when I add new InstallationSummary objects within my app. I don't understand why. When I use the List approach, the request count stays the same, even after adding more InstallationSummary objects. Can anyone explain that, too?</p>
  
  <pre><code>public IEnumerable&lt;InstallationSummary&gt; GetMostRecentByStartTime(int numberToRetrieve)
  {
      Stopwatch stopwatch = new Stopwatch();
      stopwatch.Start();
  
      try
      {
          return ExecuteQuery&lt;IEnumerable&lt;InstallationSummary&gt;&gt;(() =&gt;
          {
              List&lt;InstallationSummary&gt; installationSummaries =
                  QueryAndCacheEtags(session =&gt; session.Advanced.LuceneQuery&lt;InstallationSummary&gt;()
                  .Include(x =&gt; x.ApplicationServerId)
                  .Include(x =&gt; x.ApplicationWithOverrideVariableGroup.ApplicationId)
                  .Include(x =&gt; x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId)
                  .OrderByDescending(summary =&gt; summary.InstallationStart)
                  .Take(numberToRetrieve)).Cast&lt;InstallationSummary&gt;().ToList();
  
              List&lt;string&gt; appServerIds = (from item in installationSummaries select item.ApplicationServerId).ToList();
              List&lt;string&gt; appIds = (from item in installationSummaries select item.ApplicationWithOverrideVariableGroup.ApplicationId).ToList();
              List&lt;string&gt; groupIds = (from item in installationSummaries select item.ApplicationWithOverrideVariableGroup.CustomVariableGroupId).ToList();
  
              List&lt;ApplicationServer&gt; appServers = new ApplicationServerData().GetByIds(appServerIds).ToList();
              List&lt;Application&gt; apps = new ApplicationData().GetByIds(appIds).ToList();
              List&lt;CustomVariableGroup&gt; groups = new CustomVariableGroupData().GetByIds(groupIds).ToList();
  
              foreach (InstallationSummary summary in installationSummaries)
              {
                  summary.ApplicationServer = appServers.Where(server =&gt; server.Id == summary.ApplicationServerId).FirstOrDefault();
  
                  summary.ApplicationWithOverrideVariableGroup.Application =
                      apps.Where(app =&gt; app.Id == summary.ApplicationWithOverrideVariableGroup.ApplicationId).FirstOrDefault();
  
                  if (summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupId == null) { continue; }
  
                  summary.ApplicationWithOverrideVariableGroup.CustomVariableGroup =
                      groups.Where(group =&gt; group.Id == summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupId).FirstOrDefault();
              }
  
              return installationSummaries;
          });
      }
      finally
      {
          stopwatch.Stop();
          Debug.WriteLine("InstallationSummaryData.GetMostRecentByStartTime(): " + stopwatch.ElapsedMilliseconds);
      }
  }
  </code></pre>
  
  <p>Here is where the above method gets invoked:</p>
  
  <pre><code>protected T ExecuteQuery&lt;T&gt;(Func&lt;T&gt; func)
  {
      if (func == null) { throw new ArgumentNullException("func"); }
  
      try
      {
          return func.Invoke();
      }
      finally
      {
          Debug.WriteLine("Number of requests just before closing session: " + _session.Advanced.NumberOfRequests);
          CloseSession();
      }
  }
  </code></pre>