简体   繁体   中英

LINQ Statement foreach hour in day issue

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?

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.

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.

您可以通过以下方式一次性查询所有内容。where(p => p.DATE_TIME> = StartDate && p.DATE_TIME <= END_DATE).GroupBy(p => p.DATE_TIME.Hour)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM