I have to convert my given linq query in lambda expression. i.e.
var scholars = (from scholar in db.Scholars
join suspension in db.Suspensions
on scholar.ID equals suspension.ScholarID
where suspension.StartDate >= startDate &&
suspension.EndDate <= endDate
group scholar by new { scholar.ID, scholar.FirstName, scholar.LastName }
into g
select new
{
FullName = g.Key.FirstName +" " + g.Key.LastName,
TotalSuspensionSum = g.Sum(x => x.Suspensions.Sum(y => y.SuspensionDays))
})
.ToList()
.OrderBy(x=> x.FullName);
this is your lambda:
var scholars = db.Scholars.Join(db.Suspensions,
scholar => scholar.ID,
suspension => suspension.ScholarID,
(scholar, suspension) => new {scholar, suspension})
.Where(u => u.suspension.StartDate >= startDate &&
u.suspension.EndDate <= endDate)
.GroupBy(u => new { u.scholar.ID, u.scholar.FirstName, u.scholar.LastName })
.Select(u => new
{
FullName = u.Key.FirstName + " " + u.Key.LastName,
TotalSuspensionSum = u.Sum(x =>
x.scholar.Suspensions.Sum(y => y.SuspensionDays)
)
})
.OrderBy(x => x.FullName)
.ToList();
Well I don't think I should do all your work for you but specifically the group by you are asking about could be done like:
...GroupBy(x => new { x.ID, x.FirstName, x.LastName })...
Related
I want add a new column to find which is lasted record in group.
Can I write subquery in Select() method?
I have try this
var test = DailyPeriods.Where(x => x.BookingDate == "2016/12/30")
.Select(x =>
new
{
PERIOD_GROUP_ID = x.PeriodGroupID,
PERIOD_NAME = x.PeriodName,
New_Column = DailyPeriods
.Where(z => z.BookingDate == "2016/12/30")
.Select(a =>
new
{
PeriodGroupID = a.PeriodGroupID,
period_name = a.PeriodName
}
)
.GroupBy(b => b.period_name)
.Select(g => g.Last().PeriodGroupID)
.Contains(x.PeriodName)
})
But will occur this error
"column not in scope: A:2211708.C(BOOKING_DATE)"
Try this..
var lastRecords = periodList.GroupBy(l => l.PeriodName)
.Select(x => new { PeriodName = x.Key,
PeriodGroupId = x.OrderBy(l => l.PeriodGroupId).Last().PeriodGroupId});
var result = from period in periodList
from lastRec in lastRecords.Where(r => r.PeriodGroupId == period.PeriodGroupId
&& r.PeriodName == period.PeriodName)
.DefaultIfEmpty()
select new { period.PeriodGroupId,period.PeriodName, New_Column=lastRec==null?false:true };
I've been puzzling over this problem all morning and can't figure out how to do it in C#.
My SQL query as follows:
select a.CourseID,
a.UserID
from audit a
inner join results r on a.UserID = r.UserID
inner join Course c on a.CourseID = c.CourseID
where c.CourseType = 9 and a.Guid = 'A123F123D123AS123123'
and a.Result = 'Passed' and r.Class = 'Maths'
group by a.CourseID, a.UserID
order by a.UserID
returns exactly what I want, but I can't seem to translate it into linq format. (the format being used here is what is required in my job at the moment so please advise on this format)
So far I have the following:
var audits = auditRepository.Get(a => a.Course.CourseType == 9 && a.GUID == this.Company.GUID && a.Result == "Passed", null, null,
a => a.Course, a => a.User)
.Join(resultsRepository.Get(r => r.GUID == this.Company.GUID && r.Class == class),
a => a.UserID,
r => r.UserID,
(a, r) => new Audit
{
User = a.User,
Course = a.Course,
Result = a.Result,
Timestamp = a.Timestamp,
AuditID = a.AuditID,
UserID = a.UserID
}
)
.OrderByDescending(o => o.Timestamp)
.GroupBy(u => new { u.User, u.Course })
.Select(grp => grp.ToList())
.ToList();
However this returns duplicates.
Any advice is appreciated, thanks
H
Instead of
.Select(grp => grp.ToList())
Select only the first element from each group to exclude duplicates:
.Select(grp => grp.First())
If you need a count also:
.Select(t => new{grp = t.First(),cnt = t.Count()} )
Fix:
.Select(t => new { grp = t.First(), cnt = t.Select(s => s.AuditID).Distinct().Count() })
This works fine.g.Key is not null and has appropriate data:
var result = db.JournalEntries.Include(je => je.JournalRecords.Select(jr => jr.Account).Select(j => j.AccountParticulars))
.Where(je => je.Date >= existingLedgerTransaction.From && je.Date <= existingLedgerTransaction.To)
.SelectMany(s => s.JournalRecords)
.GroupBy(d => d.AccountParticular.Account.AccountCategory)
.Select(g => new { Name = g.Key.Name });
But this does not work as g.Key is null:
var DateFilter = new Func<JournalEntry, bool>(je => je.Date >= existingLedgerTransaction.From && je.Date <= existingLedgerTransaction.To);
var result = db.JournalEntries.Include(je => je.JournalRecords.Select(jr => jr.Account).Select(j => j.AccountParticulars))
.Where(DateFilter)
.SelectMany(s => s.JournalRecords)
.GroupBy(d => d.AccountParticular.Account.AccountCategory)
.Select(g => new { Name = g.Key.Name });
I tried the same thing in a simple console app with static collection and passing in predicate works fine. What could be the problem here?
NOTE: Lazy loading/dynamic proxy is disabled
Try
var DateFilter = new Expression<Func<JournalEntry, bool>>(je => je.Date >= existingLedgerTransaction.From && je.Date <= existingLedgerTransaction.To);
as you need to pass an expression tree to EF
for the following query can anyone please help me convert to lambda expression
SELECT p.partno,
sp.property,
count(s.serialNo) AS PropertyCount
FROM events e
JOIN Products p ON p.productguid = e.productguid
JOIN eventtypes et ON et.eventtypeguid = e.eventtypeguid
JOIN serialcontainerevent sce ON sce.EventGUID = e.EventGUID
JOIN serials s ON s.serialguid = sce.serialguid
JOIN statuses st ON st.statusguid = s.statusguid
LEFT OUTER JOIN serialproperties sp ON sp.serialguid = s.serialguid
WHERE p.partno = '21101'
AND st.code = 'NOTRECEIVED'
AND e.Field1Value = '21101'
AND e.Field2Value = '21101'
AND e.Field3Value = '21101'
AND e.Field4Value = '21101'
AND e.Field5Value = '21101'
AND sp.property = 'Delivery Date' --group by p.partno,s.serialno
GROUP BY p.partno,
sp.property
I think something as follows should get you started. Mind that you may need to optimize it depending on your actual data and relationships:
events
.Where(#event => #event.Field1Value == "21101" && #event.Field2Value == "21101" && #event.Field3Value == "21101" && #event.Field4Value == "21101" && #event.Field5Value == "21101")
.Join(products.Where(product => product.partno == "21101"), #event => #event.productguid, product => product.productguid, (#event, product) => new { #event, product })
.Join(eventtypes, y => y.#event.eventtypeguid, eventType => eventType.eventtypeguid, (y, eventType) => new { y, eventType })
.Join(serialcontainerevent, x => x.y.#event.EventGUID, serialContainerEvent => serialContainerEvent.EventGUID, (x, serialContainerEvent) => new { x, serialContainerEvent })
.Join(serials, w => w.serialContainerEvent.serialguid, serial => serial.serialguid, (w, serial) => new { w, serial })
.Join(statuses.Where(status => status.code == "NOTRECEIVED"), v => v.serial.statusguid, status => status.statusguid, (v, status) => new { v, status })
.GroupJoin(serialproperties.Where(serialProperty => serialProperty.property == "Delivery Date"), u => u.v.serial.serialguid, serialProperty => serialProperty.serialguid, (u, serialProperties) => new { u, serialProperties })
.SelectMany(t => t.serialProperties.Select(s => new { key = new { t.u.v.w.x.y.product.partno, s.property }, t }))
.GroupBy(r => r.key)
.Select(z => new { z.Key.partno, z.Key.property, PropertyCount = z.Where(q => q.t.u.v.serial.serialNo != null).Count() });
I have a SQL Query
select Firma.Name as companyName,
Taetigkeit.Taetigkeit as skillName,
SUM(Zeit) as time
from Zeiterfassung
inner join Firma On ZEiterfassung.FirmenID = Firma.ID
inner join Taetigkeit on Zeiterfassung.TaetigkeitID = Taetigkeit.ID
group by Taetigkeit, Firma.Name
order by Firma.Name
And want to "translate" it to linq. Here is what I tried:
var query = db.Zeiterfassung
.Where(x => x.Firma.ID == x.FirmenID && x.TaetigkeitID == x.Taetigkeit.ID)
.GroupBy(x => x.Taetigkeit.Taetigkeit1)
.Select(x => new Evaluation() { skillName = x.Key, time = x.Sum(y => y.Zeit), //skillName = x.Sum(x => x.Zeit), })
.OrderBy(x => x.skillName);
I dont know who to solve this with joins and the group by because all the time when i do a groupBy i cant access the other members.
From data you provided, I think query should look like
from z in db.Zeiterfassung
join f in db.Firma on z.FirmenID equals f.ID
join t in db.Taetigkeit on z.TaetigkeitID equals t.ID
select new { f.Name, t.Taetigkeit, z.Zeit) into x
group x by new { x.Taetigkeit, f.Name } into g
select new {
CompanyName = g.Key.Name,
SkillName = g.Key.Taetigkeit,
Time = g.Sum(i => i.Zeit)
}
Or with navigation properties:
db.Zeiterfassung
.Select(z => new { z.Zeit, z.Taetigkeit.Taetigkeit1, z.Firma.Name })
.GroupBy(x => new { x.Taetigkeit1, x.Name })
.Select(g => new Evaluation {
companyName = g.Key.Name,
skillName = g.Key.Taetigkeit1,
time = g.Sum(y => y.Zeit)
});