How to make group by inside group by in LINQ to Entity? - c#

I have this LINQ to Entiy :
var grouppedClientFullReview = (from cfr in clientFullReview
group cfr by new { cfr.clientId, cfr.clientName } into g
select new
{
siteNumbers = g.Select(x => x.siteId).Count(),
clientId = g.Key.clientId,
clientName = g.Key.clientName,
WorkPlanReview = new
{
frequency = g.Select(x => x.inspectionFrequency),
isNormal = g.Any(x => x.isNormal == false) ? false : true,
objectsID = g.Select(x => x.objectID).ToArray(),
}
}).ToList();
I need to implement group by in WorkPlanReview property.
My question is how can I implement group by inside WorkPlanReview?
Is it posible to make nested group by?

If you want to group by the WorkPlanReview property itself, then you can end your query in the following way:
}).GroupBy(g => g.WorkPlanReview).ToList();
If you want to group on one of WorkPlanReview's properties, here's how to achieve it:
}).GroupBy(g => g.WorkPlanReview.frequency).ToList();

Related

I didn't true use order by in linq

Hi i develop web app with c#. I have sql query and i convert to linq but it's not working true because of order by
My sql query
Select TOP 3 HastalikIsmi From Hastaliklar group by HastalikIsmi order by Count(*) desc
My linq
public List<HastalikDto> GetHastalikDto()
{
using (SirketDBContext context = new SirketDBContext())
{
var result = from hastalik in context.Hastaliklar
group hastalik by hastalik.HastalikIsmi into isim
select new HastalikDto { HastalikIsmi = isim.Key };
return result.OrderBy(h => h.HastalikIsmi).Take(3).ToList();
}
}
Here's how you can do the order by on the count of each group and take the 3 with the highest count.
var result = context.Hastaliklar
.GroupBy(x => x.HastalikIsmi)
.OrderByDescending(grp => grp.Count())
.Select(grp => grp.Key)
.Take(3)
.ToList();

How to select multiple fields (LINQ)

How to change the following linq query to select another field value Field<int>("data_entry"),i want to select multiple fields .
var a = DF_Utilities.GetAvailableTasks(empnum, 1).AsEnumerable().Where(
p => p.Field<int>("task_code") == int.Parse(drpTasks.SelectedValue)).Select(p => p.Field<int>("cand_num")).First();
p.Field<int>("cand_num"),Field<int>("data_entry")
instead of p.Field<int>("cand_num")
You can use anonymous type:
var a = DF_Utilities.
GetAvailableTasks(empnum, 1).
AsEnumerable().
Where(p => p.Field<int>("task_code") == int.Parse(drpTasks.SelectedValue)).
Select(p => new
{
candNum = p.Field<int>("cand_num"),
dataEntry = p.Field<int>("data_entry")
}).
First();

Use Linq to return first result for each category

I have a class (ApplicationHistory) with 3 properties:
ApplicantId, ProviderId, ApplicationDate
I return the data from the database into a list, however this contains duplicate ApplicantId/ProviderId keys.
I want to supress the list so that the list only contains the the earliest Application Date for each ApplicantId/ProviderId.
The example below is where I'm currently at, but I'm not sure how to ensure the earliest date is returned.
var supressed = history
.GroupBy(x => new
{
ApplicantId = x.ApplicantId,
ProviderId = x.ProviderId
})
.First();
All advice appreciated.
Recall that each group formed by the GroupBy call is an IGrouping<ApplicationHistory>, which implements IEnumerable<ApplicationHistory>. Read more about IGrouping here. You can order those and pick the first one:
var oldestPerGroup = history
.GroupBy(x => new
{
ApplicantId = x.ApplicantId,
ProviderId = x.ProviderId
})
.Select(g => g.OrderBy(x => x.ApplicationDate).FirstOrDefault());
You are selecting first group. Instead select first item from each group:
var supressed = history
.GroupBy(x => new {
ApplicantId = x.ApplicantId,
ProviderId = x.ProviderId
})
.Select(g => g.OrderBy(x => x.ApplicationDate).First());
Or query syntax (btw you don't need to specify names for anonymous object properties in this case):
var supressed = from h in history
group h by new {
h.ApplicantId,
h.ProviderId
} into g
select g.OrderBy(x => x.ApplicationDate).First();

LINQ group by with multiple counts

I am having trouble doing multiple counts on a single table in a LINQ query. I am using NHibernate, LINQ to NHibernate and C#.
query is a populated list. I have a table that has a boolean called FullRef. I want to do a LINQ query to give a count of occurances of FullRef = false and FullRef = true on each TrackId. TrackId gets a new row for each time he gets a track.Source == "UserRef".
In the following query I get the correct number count (from the FullRefTrueCount) of FullRef = true, but it gives an unknown wrong number on the FullRefFalseCount.
var query2 = from track in query
where track.Source == "UserRef"
group track by new { TrackId = track.TrackId, FullRef = track.FullRef } into d
select new FullReferrer
{
Customer = d.Key.TrackId,
FullRefFalseCount = d.Where(x => x.FullRef == false).Count(),
FullRefTrueCount = d.Where(x => x.FullRef == true).Count()
};
Anyone have any idea on how to fix it? I am pretty certain the .Where() clause is ignored and the "group by" is screwing me over.
If I could somehow
group track by new { TrackId = track.TrackId, FullRefTrue = track.FullRef, FullRefFalse = !track.FullRef }"
it would work. Is there some way to do this?
you should group by trackId only, if you want results by trackId...
var query2 = query
.Where(m => m.Source == "UserRef")
.GroupBy(m => m.TrackId)
.Select(g => new FullReferrer {
Customer = g.Key,
FullRefFalseCount = g.Count(x => !x.FullRef),
FullRefTrueCount = g.Count(x => x.FullRef)
});

How to project LINQ-to-SQL query into custom object with a GroupBy and OrderBy

I'm trying to convert this query so that it will output to a custom DTO type object. I want to get only pages with the highest revision number for the int[] that I pass in.
return from page in db.Pages
where intItemIdArray.Contains(page.pageId)
group page by page.pageId into g
orderby g.Max(x => x.pageId)
select g.OrderByDescending(t => t.revision).First();
But when I try to replace
select g.OrderByDescending(t => t.revision).First();
With something like
select (new JPage {pageid = g.pageId, title = g.title, etc})
.OrderByDescending(t => t.revision)
.First();
It doesn't work, can anyone help me out?
This is what I have gone with currently, which I don't like, but it is working perfectly, and I don't need to optimize beyond this currently.
It would be great if someone could improve this.
var pages = from page in db.Pages
where intItemIdArray.Contains(page.pageId)
group page by page.pageId into g
orderby g.Max(x => x.pageId)
select g.OrderByDescending(t => t.revision).First();
return pages.Select(x => new JPage() {
pageId = x.pageId,
pageKey = x.pageKey,
title = x.title,
body = x.body,
isFolder = x.isFolder.ToString(),
leftNode = x.leftNode,
rightNode = x.rightNode,
revision = x.revision,
sort = x.sort,
createdBy = x.createdBy.ToString(),
createdDate = Utility.DateTimeToUnixTimeStamp(x.createdDate).ToString(),
modifiedDate = Utility.DateTimeToUnixTimeStamp(x.modifiedDate).ToString(),
pageVariationId = x.pagesVariationId,
parentId = x.parentId
})
.AsQueryable();
I'd suggest that you order before you select; i.e. instead of
select (new JPage {pageid = g.pageId, title = g.title, etc}
.OrderByDescending(t => t.revision).First();
you should try
.OrderByDescending(t => t.revision)
.Select(new JPage {pageid = g.pageId, title = g.title, etc})
.First();
You can't order by 'revision' if it doesn't exist in the result of the previous 'select'
This should be a slight improvement
var pages = from page in db.Pages
where intItemIdArray.Contains(page.pageId)
group page by page.pageId into g
select g.First(a => a.revision == g.Max(b => b.revision));

Categories