I need to select date and average values from a datacontext's table and I need to group it by year and by month.
In SQL it will look like this
select Year(data) as years, Month(data) as months, Avg(value) as prices from Prices
group by Year(data),MONTH(data)
order by years, months
I've created a LINQ query
var query0 = from c in dc.Prices
where Convert.ToDateTime(c.data).CompareTo(left) >= 0
&& Convert.ToDateTime(c.data).CompareTo(right) <= 0
&& c.idsticker.Equals(x)
group c by new { ((DateTime)c.data).Year, ((DateTime)c.data).Month }
into groupMonthAvg
select groupMonthAvg;
But I don't know how to get average values in result
Use the Average function.
var query0 = from c in dc.Prices
where Convert.ToDateTime(c.data).CompareTo(left) >= 0
&& Convert.ToDateTime(c.data).CompareTo(right) <= 0
&& c.idsticker.Equals(x)
group c by new { ((DateTime)c.data).Year, ((DateTime)c.data).Month }
into groupMonthAvg
select new
{
years = groupMonthAvg.Key.Year,
months = groupMonthAvg.Key.Month,
prices = groupMonthAvg.Average(x=>x.value)
};
Just use the Average function in your select:
var query0 = from c in dc.Prices
where Convert.ToDateTime(c.data).CompareTo(left) >= 0
&& Convert.ToDateTime(c.data).CompareTo(right) <= 0
&& c.idsticker.Equals(x)
group c by new { ((DateTime)c.data).Year, ((DateTime)c.data).Month }
into groupMonthAvg
select new {
groupMonthAvg.Key.Year,
groupMonthAvg.Key.Month,
YearAverage = groupMonthAvg.Average(x=>x.Year),
MonthAverage = groupMonthAvg.Average(x=>x.Month)
};
This should do it:
var query0 = from c in dc.Prices
where Convert.ToDateTime(c.data).CompareTo(left) >= 0
&& Convert.ToDateTime(c.data).CompareTo(right) <= 0
&& c.idsticker.Equals(x)
group c by new { ((DateTime)c.data).Year, ((DateTime)c.data).Month }
into groupMonthAvg
select new { Year = groupMonthAvg.Key.Year, Month = groupMonthAvg.Key.Month, Average => groupMonthAvg.Average(i => i.value) };
Related
UPDATE m
SET m.Score = s.AScore + '-' + s.BScore
FROM #Matches m
INNER JOIN Scores s ON m.MatchId = s.MatchId
AND s.InfoTypeId = (
CASE
WHEN m.SportId = 1 AND (m.StatusId >= 13 AND m.StatusId <= 17) THEN 10
WHEN m.SportId = 1 AND m.StatusId = 20 THEN 24
WHEN m.SportId = 1 AND m.StatusId = 21 THEN 23
WHEN m.SportId = 1 AND m.StatusId = 18 THEN 8
ELSE 5
END
)
I'm having two lists in C# one is Matches and 2nd is Scores, and I want to get the result from those list like the result this query will return. Means I want to update "Score" property of "Matches" list like it is being updated in SQL query.
Any Help Please.
Matches.ForEach(m => m.Score = (Scores.Where(ms => ms.MatchId == m.MatchId
&& ms.ScoreInfoTypeId == ((m.SportId == 1 && m.StatusId >= 13 && m.StatusId <= 17) ? 10
: (m.SportId == 1 && m.StatusId == 20) ? 24
: (m.SportId == 1 && m.StatusId == 21) ? 23
: (m.SportId == 1 && m.StatusId == 18) ? 8
: 5)).Select(ms => ms.AScore + "-" + ms.BScore).FirstOrDefault()));
I have tried, but I think its too expensive. It is taking too much time. Is there any optimized way please.
Try this example in LinqPad. You can use query syntax to join the 2 lists and iterate over the result to set match scores. I used a dictionary to simplify that switch case.
void Main()
{
var matches = new[]{
new Match{MatchId=1,SportId=1,StatusId=13,Score=""},
new Match{MatchId=2,SportId=1,StatusId=18,Score=""},
new Match{MatchId=3,SportId=2,StatusId=24,Score=""},
};
var scores = new[]{
new{MatchId=1,AScore="10",BScore="0",InfoTypeId=10},
new{MatchId=2,AScore="20",BScore="0",InfoTypeId=8},
new{MatchId=3,AScore="30",BScore="0",InfoTypeId=5},
};
var dict = new Dictionary<int,int>{[13]=10,[14]=10,[15]=10,[16]=10,[17]=10,[20]=24,[21]=23,[18]=8};
var data = (from m in matches
join s in scores on m.MatchId equals s.MatchId
where s.InfoTypeId == ((m.SportId == 1 && dict.ContainsKey(m.StatusId))? dict[m.StatusId] : 5)
select new {m,s}
).ToList();
data.ForEach(o =>
{
o.m.Score = o.s.AScore + "-" + o.s.BScore;
});
matches.Dump();
}
class Match{public int MatchId; public int SportId; public int StatusId; public string Score;}
How can I do this correctly?
This is failing because schedule-on does not exist within m from RR2.
var RR = (from m in DataContext.csrcallds
where m.scheduledon >= earliestDate
&& m.scheduledon <= objdate1.DateStart
&& m.assignto == 113
&& (SqlMethods.DateDiffDay(m.scheduledon, m.completedon) > 5)
select m
);
var RR2 = RR.Select(x => (GetBusinessDays((DateTime)x.scheduledon, (DateTime)x.completedon)) > 5).ToList());
var RnR = (from m in RR2
group m by new { m.scheduledon.Value.Year, m.scheduledon.Value.Month } into p
orderby p.Key.Year ascending, p.Key.Month ascending
select new Date1()
{
theDate = DateTime.Parse($"{p.Key.Month} - {p.Key.Year}"),
theCount = p.Count(),
theString = $"{p.Key.Month} - {p.Key.Year}"
});
I am trying to query all the results.
Then use my GetBusinessDay function to filter out the ones I don't need, gathering only the records within 5 business days.
Then put the results into my Model named Date1.
I'm trying to do it like this because I cannot use GetBusinessDays within an LINQ query.
So I'm trying to filter it outside of SQL, then group the records again.
How do I go about accomplishing this task?
You could add this to your SQL Query to filter out the weekend days.
SELECT *
FROM your_table
WHERE ((DATEPART(dw, date_created) + ##DATEFIRST) % 7) NOT IN (0, 1)
Or This
select [date_created]
from table
where DATENAME(WEEKDAY, [date_created]) <> 'Saturday'
and DATENAME(WEEKDAY, [date_created]) <> 'Sunday'
Or if you have to stick to LINQ try the ideas outlined here:
Linq query DateTime.Date.DayOfWeek
DateTime firstSunday = new DateTime(1753, 1, 7);
var bookings = from b in this.db.Bookings
where EntityFunctions.DiffDays(firstSunday, b.StartDateTime) % 7 == 1
select b;
Solved by using function workdays server side:
https://stackoverflow.com/a/252532/6157660
Allows me to make a simple LINQ query, and gives me what I need.
I did edit the function to remove the +1 from DateDiff. as same days should be 0 not 1.
Thank you guys for your help!
var RnR = (from m in DataContext.csrcallds
where m.scheduledon >= earliestDate
&& m.scheduledon <= objdate1.DateStart
&& m.assignto == 113
&& (DataContext.fn_WorkDays((DateTime)m.scheduledon, (DateTime)m.completedon)) > 5
group m by new { m.scheduledon.Value.Year, m.scheduledon.Value.Month } into p
orderby p.Key.Year ascending, p.Key.Month ascending
select new Date1()
{
theDate = DateTime.Parse($"{p.Key.Month} - {p.Key.Year}"),
theCount = p.Count(),
theString = $"{p.Key.Month} - {p.Key.Year}"
});
First I want to say hello, I'm new to this site ;-)
My problem is to transform the following sql-query into a c# linq-query.
( I HAVE searched hard for an existing answer but I'm not able to combine the solution for
the joins on multiple conditions and the grouping / counting ! )
The sql-query :
DECLARE #datestart AS DATETIME
DECLARE #dateend AS DATETIME
SET #datestart = '01.04.2014'
SET #dateend = '30.04.2014'
SELECT md1.value AS [controller],md2.value AS [action], COUNT(md2.value) AS [accesscount], MAX(re.TIMESTAMP) AS [lastaccess] FROM recorderentries AS re
INNER JOIN messagedataentries AS md1 ON re.ID = md1.recorderentry_id AND md1.position = 0
INNER JOIN messagedataentries AS md2 ON re.ID = md2.recorderentry_id AND md2.position = 1
WHERE re.TIMESTAMP >= #datestart AND re.TIMESTAMP <= #dateend
AND re.messageid IN ('ID-01','ID-02' )
GROUP BY md1.value,md2.value
ORDER BY [accesscount] DESC
Any suggestions are welcome ...
What i have so far is this :
var _RecorderActionCalls = (from r in _DBContext.RecorderEntries
join m1 in _DBContext.MessageDataEntries on
new {
a = r.ID,
b = 0
} equals new {
a = m1.ID,
b = m1.Position
}
join m2 in _DBContext.MessageDataEntries on
new {
a = r.ID,
b = 0
} equals new {
a = m2.ID,
b = m2.Position
}
where r.TimeStamp >= StartDate & r.TimeStamp <= EndDate & (r.MessageID == "VAREC_100_01" | r.MessageID == "VAAUTH-100.01")
group r by new { md1 = m1.Value, md2 = m2.Value } into r1
select new { controller = r1.Key.md1, action = r1.Key.md2, count = r1.Key.md2.Count() }).ToList();
But this throws an exception ( translated from german ) :
DbExpressionBinding requires an input expression with a Listing Result Type ...
UPDATE : Back with headache ... ;-)
I found a solution to my problem :
var _RecorderActionCalls = _DBContext.RecorderEntries
.Where(r => r.TimeStamp >= StartDate & r.TimeStamp <= EndDate & (r.MessageID == "VAREC_100_01" | r.MessageID == "VAAUTH-100.01"))
.GroupBy(g => new { key1 = g.MessageData.FirstOrDefault(md1 => md1.Position == 0).Value, key2 = g.MessageData.FirstOrDefault(md2 => md2.Position == 1).Value })
.Select(s => new {
ControllerAction = s.Key.key1 + " - " + s.Key.key2,
Value = s.Count(),
Last = s.Max(d => d.TimeStamp)
}).ToList();
With this syntax it works for me. Thank you for thinking for me :-)
Something like that:
List<string> messageIdList = new List<string> { "ID-01", "ID-02" };
from re in RecorderEntries
from md1 in MessageDataEntries
from md2 in MessageDataEntries
where re.ID = md1.recorderEntry_id && md1.position == 0
where re.ID = md2.recorderEntry_id && md2.position == 1
where idList.Contains(re.messageid)
let joined = new { re, md1, md2 }
group joined by new { controller = joined.md1.value, action = joined.md2.value } into grouped
select new {
controller = grouped.Key.controller,
action = grouped.Key.action,
accesscount = grouped.Where(x => x.md2.value != null).Count(),
lastaccess = grouped.Max(x => x.re.TimeStamp) }
I have a Dictionary and want to get the average of attendances from a specific timeframe.
So far I have this working which gives me the numbers of attendances:
var vCounts = (from pil in planInfoList
from s in pil.Value
where (s.CheckInActualUtc.TimeOfDay >= TStart
&& s.CheckInActualUtc.TimeOfDay <= TEnd)
select s).Count();
The s.CheckInActualUtc is multiple dates.
How to get the avarage of attendances?
I have tried this, but this is a no go:
var vAverage = from pil in planInfoList
from s in pil.Value
where (s.CheckInActualUtc.TimeOfDay >= TStart
&& s.CheckInActualUtc.TimeOfDay <= TEnd)
group s by s.CheckInActualUtc.DayOfYear into g
select new { av = g.Average() };
If you mean, you want the average of the number of attendees per day:
var vAverage = (from pil in planInfoList
from s in pil.Value
where (s.CheckInActualUtc.TimeOfDay >= TStart
&& s.CheckInActualUtc.TimeOfDay <= TEnd)
group s by s.CheckInActualUtc.DayOfYear into g
select g.Count()).Average();
I have a timesheet entries as below
ActivityCode : Duration
Project A: 12h:31mins
Project B: 00h:10mins
Project A: 01h:10mins
Project A: 12h:31mins
Project C: 12h:31mins
Project B: 00h:10mins
Project B: 01h:10mins
Project A: 12h:31mins
What is the correct way to group the projects and aggregate their total time spent? i'm trying the below
var summary = from entry in DbSet
where entry.Timesheet.UserID == userid &&
entry.Timesheet.DateSubmitted >= startdate &&
entry.Timesheet.DateSubmitted <= enddate
group entry by entry.ActivityCode.ActivityCode1
into groupEntry
select new TimeSheetSummary()
{
ActivityCode = groupEntry.Key,
HourSpent = Convert.ToInt32(groupEntry.Sum(x => x.Duration)),
Percentage = (Convert.ToInt32(groupEntry.Sum(x => x.Duration)) / 8) * 100,
MinuteSpent = Convert.ToInt32(groupEntry.Sum(x => x.Duration)) * 60,
};
If you want to get a percentage, get a count of the number of activites and use that to divide by.
Not sure if you will need a divide by 0 check here. I'm not sure what the second LINQ will do if there's no data to begin with. Not sure if that would raise an error or not.
Int32 numberOfProjects = (from entry in DbSet
where entry.Timesheet.UserID == userid &&
entry.Timesheet.DateSubmitted >= startdate &&
entry.Timesheet.DateSubmitted <= enddate
select entry.ActivityCode.ActivityCode1).Distinct().Count();
var summary = from entry in DbSet
where entry.Timesheet.UserID == userid &&
entry.Timesheet.DateSubmitted >= startdate &&
entry.Timesheet.DateSubmitted <= enddate
group entry by entry.ActivityCode.ActivityCode1
into groupEntry
select new TimeSheetSummary()
{
ActivityCode = groupEntry.Key,
HourSpent = Convert.ToInt32(groupEntry.Sum(x => x.Duration)),
Percentage = (Convert.ToInt32(groupEntry.Sum(x => x.Duration)) / numberOfProjects) * 100,
MinuteSpent = Convert.ToInt32(groupEntry.Sum(x => x.Duration)) * 60,
};
Here's what i found as answer based on the inputs by others in the thread. thanks!
var groupEntries = from entry in DbSet
where entry.Timesheet.UserID == userId &&
entry.Timesheet.TimeSheetDate <= endDate.Date &&
entry.Timesheet.TimeSheetDate >= startDate.Date
group entry by entry.ActivityCode
into groupEntry
select new
{
ActivityCode = groupEntry.Key,
Duration = Convert.ToInt16(groupEntry.Sum(r => r.Duration))
};
var totalDuration = groupEntries.Sum(r => r.Duration);
var result = from groupEntry in groupEntries
select new TimeSheetSummary()
{
ActivityCode = groupEntry.ActivityCode,
HourSpent = groupEntry.Duration / 60,
MinuteSpent = groupEntry.Duration % 60,
Percentage = groupEntry.Duration / totalDuration * 100
};