How to use Min() and Max() in Linq SQL queries [duplicate] - c#

I plan on using this in a subquery but can't figure out the correct syntax to translate the following query into LINQ:
select ChapterID, min(MeetingDate)
from ChapterMeeting
group by ChapterID

var query = myDataContext.ChapterMeeting
.GroupBy(cm => cm.ChapterID)
.Select(g => new {
g.Key,
MinMeetingDate = g.Min(cm => cm.MeetingDate)
});

Well, Amy beat me to it, but in case you wanted to see it with the "comprehension" syntax:
var q = (
from cm in context.ChapterMeeting
group cm by cm.ChapterID into cmg
select new {
ChapterID = cmg.Key,
FirstMeetingDate = cmg.Min(cm => cm.MeetingDate)});

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();

EF LINQ Group By and Sum

I'm trying to do select with group by and sum while selecting other columns using LINQ and i come out with this
var inputList = from c in db.InputItem
join o in db.ItemsDefinition on c.ItemsDefinitionID equals o.ItemsDefinitionID
group c by new { c.ItemsDefinitionID, o.ItemsAName } into g
select new
{
Name = g.Key,
Sum = g.Sum(c => c.Quantity)
};
what I'm trying to do is to preform this SQL statement
Select i.ItemsDefinitionID,
ID.ItemsAName,
sum(Quantity) as avialable
from InputItem i
Left Outer Join ItemsDefinition ID On i.ItemsDefinitionID=ID.ItemsDefinitionID
group by i.ItemsDefinitionID,ID.ItemsAName
Warm Thanks
you can do this way too:
var inputList = d.InputItem
.GroupBy(s =>s.ItemsDefinitionID, s.ItemsDefinition.AName)
.Select(g => new
{
ItemsDefinitionID=g.Key.ItemsDefinitionID,
Name = g.Key.AName,
Available= g.Sum(s =>s.Quantity),
})
.ToList();
You don't really need to do manual joins in EF if your relationships are properly defined in the model.
This query will suffice
var result = db.ItemsDefinition.Select(id => new { id.ItemsDefinitionID,
id.ItemsAName, Quantity = id.Items.Sum(i => i.Quantity) });
Either leave the SQL generation to EF or stop using EF. There's no point in using an ORM if you keep worrying about the queries it will generate.

Lambda Group By Max

I have this query.
select distinct game_id, max(event_number) as LatestEvent from Source group by game_id
But I would like this converted to its Linq or Lambda equivalent and I havent found a way to do so properly. Can someone advise.
Thanks for your time.
var q = db.Table
.GroupBy(x => x.game_id)
.Select(g => new { game_id = g.Key, LatestEvent = g.Max(x => x.event_number) });

Convert SQL query with multiple GroupBy columns to LINQ

SELECT
[TimeStampDate]
,[User]
,count(*) as [Usage]
FROM [EFDP_Dev].[Admin].[AuditLog]
WHERE [target] = '995fc819-954a-49af-b056-387e11a8875d'
GROUP BY [Target], [User] ,[TimeStampDate]
ORDER BY [Target]
My database table has the columns User, TimeStampDate, and Target (which is a GUID).
I want to retrieve all items for each date for each user and display count of entries.
The above SQL query works. How can I convert it into LINQ to SQL? Am using EF 6.1 and my entity class in C# has all the above columns.
Create Filter basically returns an IQueryable of the entire AuditLogSet :
using (var filter = auditLogRepository.CreateFilter())
{
var query = filter.All
.Where(it => it.Target == '995fc819-954a-49af-b056-387e11a8875d')
.GroupBy(i => i.Target, i => i.User, i => i.TimeStamp);
audits = query.ToList();
}
Am not being allowed to group by on 3 columns in LINQ and I am also not sure how to select like the above SQL query with count. Fairly new to LINQ.
You need to specify the group by columns in an anonymous type like this:-
var query = filter.All
.Where(it => it.Target == '995fc819-954a-49af-b056-387e11a8875d')
.GroupBy(x => new { x.User, x.TimeStampDate })
.Select(x => new
{
TimeStampDate= x.Key.TimeStampDate,
User = x.Key.User,
Usage = x.Count()
}).ToList();
Many people find query syntax simpler and easier to read (this might not be the case, I don't know), here's the query syntax version anyway.
var res=(from it in filter.All
where it.Target=="995fc819-954a-49af-b056-387e11a8875d"
group it by new {it.Target, it.User, it.TimeStampDate} into g
orderby g.Key.Target
select new
{
TimeStampDate= g.Key.TimeStampDate,
User=g.Key.User,
Usage=g.Count()
});
EDIT: By the way you don't need to group by Target neither OrderBy, since is already filtered, I'm leaving the exact translation of the query though.
To use GroupBy you need to create an anonymous object like this:
filter.All
.Where(it => it.Target == '995fc819-954a-49af-b056-387e11a8875d')
.GroupBy(i => new { i.Target, i.User, i.TimeStamp });
It is unnecessary to group by target in your original SQL.
filter.All.Where( d => d.Target == "995fc819-954a-49af-b056-387e11a8875d")
.GroupBy(d => new {d.User ,d.TimeStampDate} )
.Select(d => new {
User = d.Key.User,
TimeStampDate = d.Key.TimeStampDate,
Usage = d.Count()
} );

How to convert Linq expression with multiple joins into method syntax OR retrieve select index?

I have an existing (working!) linq expression:
from ca in db.CustomAnswer
join ss in db.SurveySubmission on ca.SubmissionId equals ss.Id
join cq in db.CustomQuestion on ca.QuestionId equals cq.Id
where (ss.SurveyId == request.SurveyId)
orderby ss.Submitted, cq.SortOrder
select new
{
SubmissionId = ss.Id,
Answer = ca.Answer
}
I want to add the index of the select into the new object, e.g.
from ca in db.CustomAnswer
join ss in db.SurveySubmission on ca.SubmissionId equals ss.Id
join cq in db.CustomQuestion on ca.QuestionId equals cq.Id
where (ss.SurveyId == request.SurveyId)
orderby ss.Submitted, cq.SortOrder
select new
{
SubmissionId = ss.Id,
**Code = selectIndex,**
Answer = ca.Answer
}
To do this, I believe I need to first convert my query to method syntax so I can use the Select((q, index) => ...) form. To my simple mind, I think it should be:
db.SurveySubmission
.Where(ss => ss.SurveyId == request.SurveyId)
.OrderBy(ss => ss.Submitted)
.Join(db.CustomAnswer, ss => ss.Id, ca => ca.SubmissionId, (ss, ca) => new { ss, ca })
.Join(db.CustomQuestion, o => o.ca.QuestionId, cq => cq.Id, (o, cq) => new { o.ss, o.ca, cq })
.OrderBy(q => q.cq.SortOrder)
.Select((q, idx) => new {
SubmissionId = q.ss.Id,
Answer = q.ca.Answer,
Code = idx
});
However, when the expression is evaluated I get an error:
LINQ to Entities does not recognize the method
'System.Linq.IQueryable1[<>f__AnonymousTypef3[System.Guid,System.String,System.Int32]]
Select[<>f_AnonymousTypee3,<>f__AnonymousTypef3]
(System.Linq.IQueryable1[<>f__AnonymousTypee3[My.Data.Namespace.SurveySubmission,
My.Data.Namespace.CustomAnswer,My.Data.Namespace.CustomQuestion]],
System.Linq.Expressions.Expression1[System.Func3[<>f_AnonymousTypee3[My.Data.Namespace.SurveySubmission,
My.Data.Namespace.CustomAnswer,My.Data.Namespace.CustomQuestion],System.Int32,<>f__AnonymousTypef3[System.Guid,
System.String,System.Int32]]])'
method, and this method cannot be translated into a store expression.
I'm hoping this is glaringly obvious to someone? I've stared at it for several hours and the only conclusion I can make is that I'm not clever enough ... can anyone help please??
EF can't translate that into SQL, because in SQL sets are unordered; the idea of an index just doesn't make any sense to it.
Instead do everything but getting the index using an EF query, and then tack on the indexes in a linq to objects query:
var query = //your original query goes here
var finalQuery = query.AsEnumerable()
.Select((answer, index) => new
{
answer.SubmissionId,
answer.Answer,
Code = index,
});

Categories