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.
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)
Related
The following query is returning a number of daily orders. I want to create another query that will return int number of orders in one month. The problem is some months have 29days, some 30 or 31. Any help is appreciated!
public int GetNewDailyOrders()
{
return _DbContext.Carts.Where(x => x.Created >= DateTime.UtcNow.AddDays(-1)).Count();
}
public int GetMonthlyOrders(int month, int year)
{
return _DbContext.Carts.Count(x => x.Created.Year == year && x.Created.Month == month);
}
may be, you should consider support different timezones, summertime or not, something like this as well
My chief complaint with Nobody's answer is that it manipulates table data, which generally kills the db's ability to use indexes
Consider instead working out the date range and querying it instead:
var n = DateTime.Now;
var f = new DateTime(n.Year, n.Month, 1);
var t = new DateTime(n.Year, n.Month + 1, 1);
_dbContext.Carts.Count(c => c.CreatedDate >= f && c.CreatedDate < t);
Fairly new with C# and still learning a lot. I'm in a pickle and wondering if I could get some help. I have researched and just cannot find the answer.
I have a foreach statement on LaborHed and I am gathering work hours based on clockin/clockout. Works great for those that don't leave the premises for lunch. These employees must clock out for lunch and then clock back in creating another LaborHed record. I am trying to combine the labor hours of the two and then determine overtime. I then write out everything to a .csv file.
Is there some sort of join or grouping or something that could be applied??
foreach (var LaborHed_iterator in (from LaborHed_Row in Db.LaborHed
where LaborHed_Row.ClockInDate >= (DateTime?)ttUD06Row.Date01 && LaborHed_Row.ClockInDate <= (DateTime?)ttUD06Row.Date02
orderby LaborHed_Row.EmployeeNum, LaborHed_Row.ClockInDate
select LaborHed_Row))
{
LaborHed2 = (from LaborHed2_Row in Db.LaborHed
where LaborHed2_Row.ClockInDate == LaborHed.ClockInDate && LaborHed2_Row.EmployeeNum == strEmpNum
select LaborHed2_Row). // All LaborHed records for selected ClockinDate by Employee for Shop Employees only
if (LaborHed2 != null)
{
}
}
Any help would be greatly appreciated!
Thanks in advance,
Chris
Try:
var empWorkTimes = Db.LaborHeds.Where(x => x.ClockInDate >= DateTime.Now && x.ClockOutDate <= DateTime.Now)
.OrderBy(x => x.ClockInDate)
.GroupBy(x => x.EmployeeNum)
.Select(x => new { EmployeeNum = x.Key, TotalHours = x.Sum(l => (l.ClockOutDate - l.ClockInDate).TotalHours) });
I have the following code in my BLL which is accessed via a WCF service call:
public List<Dispatch> GetDispatchesByDateRange(DateTime start, DateTime end, params string[] includes)
{
MyEntities entities = new MyEntities();
var res = from d in entities.Dispatches
where d.Route.Legs.Any(x =>
x.StartPoint.ArrivalTime >= start && x.StartPoint.ArrivalTime <= end ||
x.StartPoint.DepartureTime >= start && x.StartPoint.DepartureTime <= end ||
x.EndPoint.ArrivalTime >= start && x.EndPoint.ArrivalTime <= end ||
x.EndPoint.DepartureTime >= start && x.EndPoint.DepartureTime <= end)
select d;
ObjectQuery<Dispatch> query = res as ObjectQuery<Dispatch>;
foreach (string s in includes)
query.Include(s);
return query.ToList();
}
One of the calls from the client side sends a few includes along to eager load related entities. The problem I'm running into is that the Includes are being ignored. I've read that EF will ignore includes when used in a subquery or as part of a projection. I'm not doing either of those in this case, just selecting the entire entity based on a where condition and then appending the includes. If I don't use a where condition, the includes come across just fine. Has anyone else run into this situation where simply adding a where condition causes includes to be ignored? Could it be because my 'where' digs down into the relationship hierarchy too far?
You can try to call Include extension methods before Where().
In EF 5 it can be done as
DbQuery<Dispatch> query = entities.Dispatches;
foreach (var include in includes)
{
query = query.Include(include);
}
var res = from d in dispatches
where ...
select d;
Finally got this working, had to use this formulation:
ObjectQuery<Dispatch> query = (from item in entities.Dispatches select item) as ObjectQuery<Dispatch>;
foreach (string s in includes)
query = query.Include(s);
var res = from d in query
where d.Route.Legs.Any(x =>
x.StartPoint.ArrivalTime >= start && x.StartPoint.ArrivalTime <= end ||
x.StartPoint.DepartureTime >= start && x.StartPoint.DepartureTime <= end ||
x.EndPoint.ArrivalTime >= start && x.EndPoint.ArrivalTime <= end ||
x.EndPoint.DepartureTime >= start && x.EndPoint.DepartureTime <= end)
select d;
Essentially, the main difference is that I'm doing an initial linq query, then attaching the includes and finally reselecting from that group with the where condition.
I had the same issue, EF ignoring Include() for no reason. I worked around it by using a subquery. Not the best solution, but couldn't find another working one... Snippet below. Edit: You could probably replace this by a join as well, didn't have time to test it.
Note: I'm using EF Core RC1 at time of writing (not my decision).
var result = projs.Select(p => new FoundProject
{
ProjectId = p.Id,
ProjectName = p.Name,
ProjectEntityTypeId = p.ProjectEntityTypeId,
ProjectEntityType = context.ProjectEntityTypes.Where(e => e.Id == p.ProjectEntityTypeId).Select(e => e.Name).FirstOrDefault(),
RentStatus = p.RentStatus,
RentPrice = p.RentPrice
});
I'm trying to code the following SQL statement into LINQ, but struggling. Here is the SQL statement:
SELECT C.ITM_CD, C.BUY_QTY, C.COST
FROM CST C
WHERE C.eff_dt IN (SELECT MAX (D.eff_dt)
FROM CST D
WHERE D.itm_cd = C.itm_cd
AND D.eff_dt <= '22-APR-2014')
ORDER BY C.itm_cd
And here is my LINQ attempt that brings nothing back, even though EVERY eff_dt has a date less than today's date and keep in mind, in my 'real' program this date will be changing.
var results = from c in Csts
let MaxEffDate = (from d in Csts
where d.EffDt <= DateTime.Parse("04/22/2014").Date
&& d.ItmCd == c.ItmCd
select d.EffDt).Max()
where c.EffDt.Equals(MaxEffDate)
select new
{
c.ItmCd,
c.BuyQty,
c.Content
};
Lambda code would be great! So for each itm_cd row in the CST table, I want all the rows to come back that have the Max effective date for that itm_cd as long as the eff_dt <= a certain date. I hard-coded today's date so that I know every row should be coming back, but I get nothing.
I've seen a lot of sub-selects on this site but they always use the MAX function without a WHERE clause of <= for that MAX column.
I can't really test this at the moment, but something like this should get you close:
var results = Csts.Where(d =>
d.EffDt == Csts.Where(x =>
x.ItmCd == d.ItmCd &&
x.EffDt <= DateTime.Now)
.Max(x => x.EffDt))
.OrderBy(d => d.ItmCd)
.Select(d => new { d.ItmCd, d.BuyQty, d.Content });
I have a problem; actually I am having workingHours in my database table in the format HH.mm and I want to sum all the working hours using LINQ can any 1 please tell how to do this.
In totalWeekHours I have all the working hours and I have replace HH.mm format in HH:mm but I don't know how to parse it in timespan and then Sum() using Linq.
please help.
var totalWeekHours = (from twh in db.MytimeMaster
where ((twh.date >= lstsun && twh.date <= tilldate)
&& (twh.agentID == agentid))
select twh.totalworkinghours).ToList();
if (totalWeekHours.Count > 0)
{
List cnvrtToTimespanlist = new List();
foreach(var list in totalWeekHours)
{
cnvrtToTimespanlist.Add(list.ToString().Replace('.', ':'));
}
}
You can use Aggregate method.
var sum = (from twh in db.MytimeMaster
where ((twh.date >= lstsun && twh.date <= tilldate) && (twh.agentID == agentid))
select twh.totalworkinghours).Aggregate(TimeSpan.FromMinutes(0), (total, next) => total + next);
p.s. assume used TimeSpan for time intervals.