Reputation: 2207
I have the following statement that is taking a long time to load. Can anyone advise me how i can solve this performance issue and still get the same result a count for each hour. I have to loop though each machine first and loop through each hour for each machine.
foreach (string MachineID in this.lboxMachines.SelectedItems)
{
if (this.lboxMachines.SelectedItems.Contains(GimaID))
{
{
for (int i = 0; i <= 23; i++)
{
var PartsCast = (from p in ProductionEntity.PARTDATAs
where p.DATE_TIME >= StartDate
where p.DATE_TIME <= EndDate
where p.MACHINE == MachineID
select p).Count();
StartDate.AddHours(1);
DT.Rows[row][col] = PartsCast;
col++;
}
}
}
}
Would i be better doing one statement for each machine or leave it how it is?
Upvotes: 0
Views: 223
Reputation: 31616
I believe you are having the code get things multiple times due to IQueryable nature of Linq which would be causing the slow down. Let us break it down into steps to see if we can lesson the impact.
One needs to nail down what is not changing by getting it into a list and away from IQueryable. In the example below, I am ignoring where the data is going, just giving you the processing needed and a structure to extract the info.
// Get the machines to process only once by not getting a queryable.
var machines =
this.lboxMachines.SelectedItems
.Where( machine => machine.Contains(GimaID) )
.ToList(); // Don't keep this IQueryable but as a hard list by this call.
// Get *only* the parts to use; using one DB call
var parts = ProductionEntity.PARTDATAs
.Where(part => machines.Contains(part.Machine))
.ToList();
// Now from the parts get the count based off of the time each hour
var resultPerHour =
Enumerable.Range(0, 24)
.Select (hour => new
{
Hour = hour,
Count = parts.Count(part => part.DATETIME >= StartDate.AdHours(hour) && part.DATETIME <= EnDate)
});
resultPerHour
can now be reported to the user.
Note if parts
result is too big for the memory, then remove the .ToList on it and use it as IQueryable.
Upvotes: 1
Reputation: 150
You could query all in one go by doing .Where(p => p.DATE_TIME >= StartDate && p.DATE_TIME <= END_DATE).GroupBy(p => p.DATE_TIME.Hour)
Upvotes: 0
Reputation: 402
Based on you code try this
if (this.lboxMachines.SelectedItems != null && this.lboxMachines.SelectedItems.Contains(GimaID))
{
foreach (string MachineID in this.lboxMachines.SelectedItems)
{
for (int i = 0; i <= 23; i++)
{
var PartsCast = (from p in ProductionEntity.PARTDATAs
where p.DATE_TIME >= StartDate
where p.DATE_TIME <= EndDate
where p.MACHINE == MachineID
select p).Count();
StartDate = StartDate.AddHours(1);
DT.Rows[row][col] = PartsCast;
col++;
}
}
}
but i don't see where you define variables row, col and StartDate.
Upvotes: 0