I have the following LINQ query but i want to modify it that I want to group by staffId and pick only those records whose ObservationDate is Max for each staffId.
from ob in db.TDTObservations.OfType<TDTSpeedObservation>()
select new
{
Id = ob.ID,
AcademicYearId = ob.Teachers.FirstOrDefault().Classes.FirstOrDefault().AcademicYearID,
observationDate = ob.ObservationDate,
schoolId = ob.Teachers.FirstOrDefault().Classes.FirstOrDefault().SchoolID,
staffId=ob.Teachers.FirstOrDefault().ID
};
var observations =
from ob in db.TDTObservations.OfType<TDTSpeedObservation>()
select new {
Id = ob.ID,
AcademicYearId = ob.Teachers.FirstOrDefault().Classes.FirstOrDefault().AcademicYearID,
observationDate = ob.ObservationDate,
schoolId = ob.Teachers.FirstOrDefault().Classes.FirstOrDefault().SchoolID,
staffId=ob.Teachers.FirstOrDefault().ID
};
var result = from o in observations
group o by o.staffId into g
select g.OrderByDescending(x => x.observationDate).First();
what about this: hereby you first group your entries (Teachers) by their ID together and then from each group (grp) you pick that one with the latest ObservationDate
var observations = from d in db.TDTObservations.OfType<TDTSpeedObservation>()
group d by d.Teachers.FirstOrDefault().ID into grp
select grp.OrderByDescending(g => g.ObservationDate).FirstOrDefault();
Related
What could be the LINQ query for this SQL?
SELECT PartId, BSId,
COUNT(PartId), MAX(EffectiveDateUtc)
FROM PartCostConfig (NOLOCK)
GROUP BY PartId, BSId
HAVING COUNT(PartId) > 1
I am actually grouping by two columns and trying to retrieve max EffectiveDateUtc for each part.
This is what I could write. Stuck up on pulling the top record based on the date.
Also not sure, if this is a optimal one.
//Get all the parts which have more than ONE active record with the pat
//effective date and for the same BSId
var filters = (from p in configs
?.GroupBy(w => new
{
w.PartId,
w.BSId
})
?.Select(g => new
{
PartId = g.Key.PartId,
BSId = g.Key.BSId,
Count = g.Count()
})
?.Where(y => y.Count > 1)
select p)
?.Distinct()?.ToList();
var filteredData = (from p in configs
join f in filters on p.PartId equals f.PartId
select new Config
{
Id = p.Id,
PartId = p.PartId,
BSId = p.BSId,
//EffectiveDateUtc = MAX(??)
}).OrderByDescending(x => x.EffectiveDateUtc).GroupBy(g => new { g.PartId, g.BSId }).ToList();
NOTE: I need the top record (based on date) for each part. Was trying to see if I can avoid for loop.
The equivalent query would be:
var query =
from p in db.PartCostConfig
group p by new { p.PartId, p.BSId } into g
let count = g.Count()
where count > 1
select new
{
g.Key.PartId,
g.Key.BSId,
Count = count,
EffectiveDate = g.Max(x => x.EffectiveDateUtc),
};
If I understand well, you are trying to achieve something like this:
var query=configs.GroupBy(w => new{ w.PartId, w.BSId})
.Where(g=>g.Count()>1)
.Select(g=>new
{
g.Key.PartId,
g.Key.BSId,
Count = g.Count(),
EffectiveDate = g.Max(x => x.EffectiveDateUtc)
});
select description, min(date), max(date), sum(value1), sum(value2) from table
where description = 'Axxx' and filter = 'L'
group by description
How to perform this query using Linq / C#?
Not tested, but the following should work:
table
.Where(x=>x.description=="Axxx" && x.filter=="L")
.GroupBy(x=>x.description)
.Select(x=>new {
description=x.Key,
mindate=x.Min(z=>z.date),
maxdate=x.Max(z=>z.date),
sumvalue1=x.Sum(z=>z.value1),
sumvalue2=x.Sum(z=>z.value2)
});
something like this should work. not tested
var q = from b in table
group b by b.Owner into g
where description = 'Axxx'
select new
{
description = g.description ,
date = g.min(),
date = g.max(),
value1= g.Sum(item => item.value1),
value2= g.Sum(item => item.value2),
};
That should work
var q = from s in db.table
where description = 'Axxx' and filter = 'L'
group s by s.description into g
select new {YourDescription = g.description, MaxDate = g.Max(s => s.date) }
That answer may help, too .. here
I have the following LINQ query:
summaries = from m in _master
join d in _detail on pk + m.RowKey equals d.PartitionKey into outer
from d in outer.DefaultIfEmpty()
select new
{
Position = m.Position,
Title = m.Title,
Detail = ((d == null) ? 0 : 1),
PartitionKey = m.PartitionKey,
RowKey = m.RowKey,
Modified = m.Modified,
ModifiedBy = m.ModifiedBy
} into split
group split by split.Title into g
select new AdminSummary
{
Position = g.Last().Position,
Title = g.Key,
DetailCount = g.Sum(s => s.Detail),
PartitionKey = g.Last().PartitionKey,
RowKey = g.Last().RowKey,
Modified = g.Last().Modified,
ModifiedBy = g.Last().ModifiedBy
};
The query works well but now I would like to do an order by on Position (double) followed by Title (string).
Can someone advise how I can do this?
Can someone tell me how to do the order by?
It's pretty easy:
summaries = summaries.OrderBy(item =>item.Position).ThenBy(item =>item.Title);
Also you can use OrderByDescending() and ThenByDescending() if you need them in descending order
Do this after your above query.
summaries = from s in summaries
orderby s.Position,s.Title
select s
How can I execute the following SQL-Query using LINQ or HQL?
SELECT `year`, `month`, COUNT(code_id)
FROM (SELECT DISTINCT request_codes_id AS code_id,
YEAR(requested) AS `year`, MONTH(requested) AS `month` FROM requests) r
GROUP BY `year`, `month`
ORDER BY `year`, `month`;
I tried the following:
var items = from r in TestaccountRequest.Queryable
group r by r.RequestCodeId into g
select g.First();
var grouped = from r in items
group r by r.Requested.ToString("yyyyMM") into y
select new { Year = y.First().Requested.Year, Month = y.First().Requested.Month, Count = y.Count() };
which threw a System.String ToString(System.String) NotSupportedException.
UPDATE:
The g.First() in the first LINQ-Query seems to cause the problem, because if I only run the first one I get a Code supposed to be unreachable-Exception, but if I remove the .First() it "works", but does not return what I need.
Group by an anonymous type instead:
var grouped = from r in items
group r by new { Year = r.Requested.Year,
Month = r.Requested.Month } into g
select new { g.Key.Year, g.Key.Month, Count = g.Count() };
I kinda solved it using the following:
var items = from r in TestaccountRequest.Queryable
group r by r.RequestCodeId into g
select g.ElementAt(0);
var grouped = from r in items.ToList()
group r by new { Year = r.Requested.Year,
Month = r.Requested.Month } into g
select new { g.Key.Year, g.Key.Month, Count = g.Count() };
but I gues thats not the best solution as all objects are getting fetched from the DB, but at least it is working for now, but please provide a better solution if available.
EDIT:
I now solved it using HQL:
HqlBasedQuery query = new HqlBasedQuery(typeof(ActivationCodeTestaccountRequestRecord),
"SELECT DISTINCT r.ActivationCodeId, YEAR(r.Requested), MONTH(r.Requested) " +
"FROM ActivationCodeTestaccountRequestRecord r");
var items = from object[] row in (ArrayList)ActiveRecordMediator.ExecuteQuery(query)
group row by new { Year = row[1], Month =row[2] } into g2
select new { Year = g2.Key.Year, Month = g2.Key.Month, Count = g2.Count() };
Given the following:
DP_DatabaseTableAdapters.EmployeeTableAdapter employeetableAdapter = new DP_DatabaseTableAdapters.EmployeeTableAdapter();
DP_Database.EmployeeDataTable employeeTable = employeetableAdapter.GetData();
var leadEmployees = from e in employeeTable
where e.IsLead == true
select e;
DP_DatabaseTableAdapters.LaborTicketTableAdapter tableAdapter = new DP_DatabaseTableAdapters.LaborTicketTableAdapter();
DP_Database.LaborTicketDataTable table = tableAdapter.GetDataByDate(date.ToString("MM/dd/yyyy"));
var totHours = from l in table
join e in leadEmployees on l.EmployeeID equals e.EmployeeID
group l by l.EmployeeID into g
orderby g.Key
select new
{
EmployeeID = g.Key,
HoursWorked = g.Sum(s => s.HoursWorked)
};
Total hours correctly filters the results based on the leadEmployee's list of people who have the IsLead bit set to true.
I would like to know how to do this with a where clause, I have attempd to use leadEmployees.Contanis but it wants a whole EmployeeRow...
How can I add what looks to be part of an IN clause to a where filter to replace the join?
var totHours = from l in table
where ??????
group l by l.EmployeeID into g
orderby g.Key
select new
{
EmployeeID = g.Key,
HoursWorked = g.Sum(s => s.HoursWorked)
};
The contains will only want a whole EmployeeRow if you are selecting whole employee roles. You can either:
leadEmployees.Select(e => e.id).contains
OR
leadEmployees.Count(e => e.id == l.id) > 0
Both will work. (Excuse slightly rushed lack of consideration for syntax accuracies).
This should work:
var leadEmployees = from e in employeeTable
where e.IsLead == true
select e.EmployeeID;
var totHours = from l in table
where leadEmployees.Contains(l.EmployeeID)
group l by l.EmployeeID into g
orderby g.Key
select new
{
EmployeeID = g.Key,
HoursWorked = g.Sum(s => s.HoursWorked)
};