Entity Framework equivalent of datepart(qq, getdate) - entity-framework

I have the following SQL query which I want to translate to EF query
Select Year(_r.IssueDate) as Year, datepart(qq, _r.IssueDate) as Quarter,count(*) as TotalBillableRecords, SUM(_r.BillableHours) as TotalHOurs
FROM
(select _b.Name, _i.IssueDate, _ie.BillableHours from Beneficiaries _b
join [Beneficiaries.Invoices] _i on _b.Id = _i.BeneficiaryId
join [Beneficiaries.Invoices.Entries] _ie on _ie.InvoiceId = _i.Id
where BeneficiaryId = 1) as _r
group by Year(_r.IssueDate), datepart(qq, _r.IssueDate)
This results in this
And this is what I would also want to have in my linq expression
How can I translate this to EF query ? I've tried like so
var query =
from beneficiary in _dbContext.Beneficiaries
where beneficiary.Id == beneficiaryId
from invoice in beneficiary.Invoices
//where invoice.IssueDate >= since
//where invoice.IssueDate.Month > notBefore && invoice.IssueDate.Month <= notAfter
from invoiceEntry in invoice.InvoiceEntries
group new
{
beneficiary,
invoiceEntry,
}
by new
{
Year = beneficiary.InvoiceMeta.IssueDate.Year,
Quarter = (beneficiary.InvoiceMeta.IssueDate.Month - 1) / 3 + 1,
}
into #group
select new
{
Year = #group.Key.Year,
Quarter = #group.Key.Quarter,
Hours = #group.Sum(x => x.invoiceEntry.BillableHours),
};
var y = query.ToList();
But the result is as following
[0] = Quarter = 3, Year = 2022, Hours = 6729.0
And this is it, only one entry.
What I'm noticing is that it only takes the last quarter composed of 3 months, (because the last would be the one which is not finished yet)
The class hierarchy is
Beneficiary 1-* Invoice 1-* Entries

Related

How to summarize DateTime-fields in EF6

again, I'm struggeling with Linq or EF6.
I have a table with columns (DateTime)[BeginOfWork] and (DateTime)[EndOfWork].
Now, I need to substract the BeginOfWork-value from the EndOfWork-value. From this result, I need to build a total sum.
In SQL, it looks like this:
SELECT Timesheets.EmployeeId, Sum(DateDiff("h",[Timesheets].[BeginOfWork],[Timesheets].[EndOfWork])) AS HoursOfWork
FROM Timesheets
GROUP BY Timesheets.EmployeeId
HAVING (((Timesheets.EmployeeId)=1));
How do I do this in EF6?
Actually, not working some variations of that:
int employeeId = 1;
var timesheetSum = (from ts in db.Timesheets
where (ts.EmployeeId == employeeId)
select new
{
hoursOfWork = DbFunctions.DiffHours(ts.BeginOfWork, ts.EndOfWork)
}).Sum(ts => ts.hoursOfWork);
The above results in integer rounded hoursOfWork, that don't include minutes.
So I tried that:
var timesheetSum = (from ts in db.Timesheets
where (ts.EmployeeId == employeeId)
select new
{
hoursOfWork = DbFunctions.DiffMinutes(ts.BeginOfWork, ts.EndOfWork) / 60
}).Sum(ts => ts.hoursOfWork);
But here, hoursOfWork seems to be rounded (integer), so 2,5 hours will result in 2. Perhaps a conversion of the result would work but I don't get it run.
`(double)hoursOfWork` results in an error.
Perhaps someone has a link to a complete guide, how to convert SQL to Linq-queries.
SOLUTION
var timesheetSum = (from ts in db.Timesheets
where (ts.EmployeeId == employeeId && ts.TimesheetDate <= DateTime.Today)
select new
{
hoursOfWork = DbFunctions.DiffMinutes(ts.BeginOfWork, ts.EndOfWork)/60m
}).Sum(ts => ts.hoursOfWork);
decimal result = 0;
if(timesheetSum!=null)
result = (decimal)timesheetSum;
Thanks a lot
Carsten

LINQ Query Order by Month name non-alphabetically

How do I order this query by month not alphabetically? I have two columns in my db. One for the month name and one for month number.
Right now it orders months alphabetically.
var querythpmsick = (from r in db.SickLeaveRequestForms
where r.EmployeeID == id
group r by r.MonthOfHoliday into g
select new { Value = g.Key, Count1 = g.Sum(h => h.SickLeaveTaken) }
).OrderBy(e => e.Value);
If you have both the month name and the month number in your DB, then just group by the number instead of the month name:
var querythpmsick = (from r in db.SickLeaveRequestForms where r.EmployeeID == 2
group r by r.MonthOfHolidayInt into g
select new { Value = g.Key, Count1 = g.Sum(h => h.SickLeaveTaken), MonthName = g.Select(d => d.MonthOfHoliday) })
.OrderBy(e => e.Value);
Here is a DotNetFiddle with the example: https://dotnetfiddle.net/6vE4lo

Map SQL with JOIN, GROUP BY, and SUM to Entity Framework query

I'd like to map the following SQL to EF query. I found a few similar topics, but still failed to achieve the mapping. {0}...{2} are SQL parameters.
SELECT TaskGroup.Project AS Project
SUM(Datediff(minute, WorkLog.StartTime, WorkLog.EndTime)) / 60 AS Hours
FROM WorkLog INNER JOIN TaskDefinition ON WorkLog.TaskDefinitionID = TaskDefinition.ID
INNER JOIN TaskGroup ON TaskDefinition.TaskGroupID = TaskGroup.ID
WHERE WorkLog.EmployeeID = {0} AND WorkLog.Status = 5 AND
WorkLog.StartTime >= {1} AND WorkLog.EndTime < {2}
GROUP BY TaskGroup.Project
What about this?
var query = (from wl in WorkLog
join td in TaskDefinition on wl.TaskDefinitionID equals td.ID
join tg in TaskGroup on td.TaskGroupID equals tg.ID
where wl.EmployeeID == { 0} && wl.Status == 5
&& wl.StartTime >= { 1} && wl.EndTime < { 2}
select new
{
Project = tg.Project,
StartTime = wl.StartTime,
EndTime = wl.EndTime
})
.GroupBy(o => o.Project)
.Select(g => new
{
Project = g.Key,
Hours = g.Sum(o => (o.EndTime - o.StartTime).Minutes) / 60
});

Using group in Entity Framework to return model and count

I have some data, similar to this
Email Date Id
Anne 1/1/00 1
Anne 1/2/00 2
Anne 1/4/00 3
Bert 1/4/00 4
Bert 1/5/00 5
I'm trying to return the following 2 results from the above into something like
List<Model, Count>
Where Model is a class with Email and Date (most recent Date) properties, and count is the total count
var m = (from e in emailOpens
group e by e.EmailAddress into g
select new
{
Model = g.Key,
Occurance = g.Count()
}).ToList();
The issue is, the above will return only the email addresses but I change the group statement to
group e by e into g
Then naturally there is nothing to count, so my Occurrence property remains at 0
What am I missing here?
You are missing just one statement:
var m = (from e in emailOpens
group e by e.EmailAddress into g
select new
{
Model = new
{
Email = g.Key,
// Select maximum date from group
MostRecentDate = g.Max(m => m.Date)
},
Occurance = g.Count()
}).ToList();

Linq - Limit number of results by same value of a field

I have a problem with a creation of a Linq to Entities (Oracle 11g) request. Here is the
I have a table TREATMENT with three column (simplified version) : ID, STATE and APPLICATION. Here is a sample :
ID STATE APPLICATION
1 A MAJ
2 A FLUX
3 A FLUX
4 R REF
5 A REF
Now, my objectives are to retrieve the data with theses rules:
State must be A (added)
Number of rows per application below a max value
The max value is minored b the number of row with State = R (per application)
Exemple : If the max value is 1, I must retrieve row 1 and 2. (Can't retrieve row 5 since there is already a REF with state R (the row 4))
I manage to retrieve all the row when the number of R is equal or greater than the max value, but I don't see how to limit my number of result in order to respect the max value.
Here is the request :
using (Entities bdd = new Entities())
{
var treatments = from trt in bdd.TREATMENT
let app = from t in bdd.TREATMENT
where t.STATE == "R"
group t by t.APPLICATION into grouped
where grouped.Count() >= maxPerApplication
select grouped.Key
where trt.STATE == "A" && !app.Contains(trt.APPLICATION)
orderby trt.ID
select new TreatmentDto()
{
Id = trt.ID
};
result = treatments.ToList();
}
In SQL, I would use an inner request and a ROWNUM to limit the number of result, but I don't see how to do it. The only solution I see is to do the request in two parts, but I want to avoid this to maintain the consistency of the information.
I found a solution, not sure if it's the best, but it works :
using (Entities bdd = new Entities())
{
from trt in bdd.TREATMENT
where trt.STATE == "A" &&
(from trt2 in bdd.TREATMENT
where trt2.STATE == "A" && trt2.APPLICATION == trt.APPLICATION && trt2.ID <= trt.ID
select trt2).Count() <= maxPerApplication - (from appp in bdd.TREATMENT
where appp.STATE == "R"
&& appp.APPLICATION.Equals(trt.APPLICATION)
select appp).Count()
select new TreatmentDto()
{
Id = trt.ID
};
result = treatments.ToList();
}