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.
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:
Using List:
Number of requests just before closing session: 2
Number of requests just before closing session: 4
Number of requests just before closing session: 6
Number of requests just before closing session: 7
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.
Now, if I replace every instance of List with IEnumerable (and that's the only change I make), I get this output:
Using IEnumerable:
Number of requests just before closing session: 2
Number of requests just before closing session: 3
Number of requests just before closing session: 4
Number of requests just before closing session: 27
Why the difference?
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?
public IEnumerable<InstallationSummary> GetMostRecentByStartTime(int numberToRetrieve)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
try
{
return ExecuteQuery<IEnumerable<InstallationSummary>>(() =>
{
List<InstallationSummary> installationSummaries =
QueryAndCacheEtags(session => session.Advanced.LuceneQuery<InstallationSummary>()
.Include(x => x.ApplicationServerId)
.Include(x => x.ApplicationWithOverrideVariableGroup.ApplicationId)
.Include(x => x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId)
.OrderByDescending(summary => summary.InstallationStart)
.Take(numberToRetrieve)).Cast<InstallationSummary>().ToList();
List<string> appServerIds = (from item in installationSummaries select item.ApplicationServerId).ToList();
List<string> appIds = (from item in installationSummaries select item.ApplicationWithOverrideVariableGroup.ApplicationId).ToList();
List<string> groupIds = (from item in installationSummaries select item.ApplicationWithOverrideVariableGroup.CustomVariableGroupId).ToList();
List<ApplicationServer> appServers = new ApplicationServerData().GetByIds(appServerIds).ToList();
List<Application> apps = new ApplicationData().GetByIds(appIds).ToList();
List<CustomVariableGroup> groups = new CustomVariableGroupData().GetByIds(groupIds).ToList();
foreach (InstallationSummary summary in installationSummaries)
{
summary.ApplicationServer = appServers.Where(server => server.Id == summary.ApplicationServerId).FirstOrDefault();
summary.ApplicationWithOverrideVariableGroup.Application =
apps.Where(app => app.Id == summary.ApplicationWithOverrideVariableGroup.ApplicationId).FirstOrDefault();
if (summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupId == null) { continue; }
summary.ApplicationWithOverrideVariableGroup.CustomVariableGroup =
groups.Where(group => group.Id == summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupId).FirstOrDefault();
}
return installationSummaries;
});
}
finally
{
stopwatch.Stop();
Debug.WriteLine("InstallationSummaryData.GetMostRecentByStartTime(): " + stopwatch.ElapsedMilliseconds);
}
}
Here is where the above method gets invoked:
protected T ExecuteQuery<T>(Func<T> 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();
}
}