How to select count value by linq - linq

I want express sql below by linq
select catalog,queryname,COUNT(*) from doctemplatecells group by catalog,queryname
I don't know how to get count(*), thanks

Every group consists of it's key (catalog, queryname) and it's elements as represented by the IEnumerable<> implementation of the group.
So if you have a group as a result of LinQ, you can call the extension method Count() on it.
var groups = doctemplatecells.GroupBy(dtc => new { Catalog = dtc.catalog, QueryName = dtc queryname });
foreach(group in groups)
{
console.WriteLine("{0} {1} #{2}", group.Key.Catalog, group.Key.QueryName, group.Count());
}

Related

Group by with count on multiple table in LINQ

Sql query to LINQ: Both are pasted over here, getting issue in LINQ - need suggestion:
select bm.MachineId,al.AlarmId,am.AlarmName, count(al.AlarmId)AlarmCount
from BatchMachineWise bm
join AlarmLog al on bm.MachineId = al.MachineId
join Alarm am on am.AlarmId = al.AlarmId
where bm.BatchId = 12476
group by bm.MachineId,al.AlarmId,am.AlarmName
GroupBy returns IGrouping<TKey,TElement> interface which has Key property which should be used to access fields used for grouping:
select new AlarmSummary
{
MachineId = gr.Key.MachineId,
AlarmId = gr.Key.AlarmId,
AlarmName = gr.Key.AlarmName
....
}

How to write SQL translateable linq code that groups by one property and returns distinct list

I want to change code below to be sql translateable because now i get exception.
Basicallly i want list of customers from certain localisation and there could be more than one customer with the same CustomerNumber so i want to take the one that was most recently added.
In other words - distinct list of customers from localisation where "distinct algorithm" works by taking the most recently added customer if there is conflict.
The code below works only if it is client side. I could move Group By and Select after ToListAsync but i want to avoid taking unnecessary data from database (there is include which includes list that is pretty big for every customer).
var someData = await DbContext.Set<Customer>()
.Where(o => o.Metadata.Localisation == localisation)
.Include(nameof(Customer.SomeLongList))
.GroupBy(x => x.CustomerNumber)
.Select(gr => gr.OrderByDescending(x => x.Metadata.DateAdded).FirstOrDefault())
.ToListAsync();
Short answer:
No way. GroupBy has limitation: after grouping only Key and Aggregation result can be selected. And you are trying to select SomeLongList and full entity Customer.
Best answer:
It can be done by the SQL and ROW_NUMBER Window function but without SomeLongList
Workaround:
It is because it is not effective
var groupingQuery =
from c in DbContext.Set<Customer>()
group c by new { c.CustomerNumber } into g
select new
{
g.Key.CustomerNumber,
DateAdded = g.Max(x => x.DateAdded)
};
var query =
from c in DbContext.Set<Customer>().Include(x => x.SomeLongList)
join g in groupingQuery on new { c.CustomerNumber, c.DateAdded } equals
new { g.CustomerNumber, g.DateAdded }
select c;
var result = await query.ToListAsync();

LINQ Query To Return Duplicates Exclusively

I'm working on this LINQ query. I'd like the resulting list return a list of records that contain duplicates exclusively, based on the EMailAddress1 field and grouped by the EMailAddress1 field.
For instance:
emailaddress1#gmail.com
emailaddress1#gmail.com
emailaddress2#gmail.com
emailaddress2#gmail.com
emailaddress2#gmail.com
emailaddress3#gmail.com
emailaddress3#gmail.com
etc.
Any advice on this? Thanks.
var contacts = (from c in xrm.ContactSet
where c.StateCode != 1
orderby c.EMailAddress1, c.CreatedOn
descending select new {
c.FirstName,
c.LastName,
c.EMailAddress1,
c.ContactId,
c.CreatedOn }).ToList();
Based on your previous query:
var duplicatedEmails = (from c in contacts
group c by c.EMailAddress1 into g
where g.Count() > 1
select g.Key).ToList();
var duplicatedContacts = contacts.Where(c => duplicatedEmails.Contains(c.EMailAddress1));

LINQ using Group with Count and Where, easy SQL, harder in LINQ

I'm trying to display cities names where a count is greater than 1. I can do it easy in SQL and am close in LINQ but can't figure out how to use group and also get a count and display a name
var query = (from c in Consumer
group c
by new { c.City, size = c.City.Count() }
into results
select new { Name = results.Key.City })
.Where(a => size > 0);
The size part doesn't work
try this query:
var list= Consumer.GroupBy(s=>s.City)
.Select(s=>new {
City = s.Key,
size = s.Count(),
})
.Where(s=>s.size>0).ToList();

Linq extract a count() value from a data object

I have divAssignments that has potential multiple rows by rNI, an official id, according to a compound key of Indictment and booking numbers.
rNI Booking Indictment
12345 954445 10 12345
12345 954445 10 12346
12345 954445 10 12347
So ID has a count of 3 for a single booking number for this rni.
I get lost attempting to generate a count and a group by booking Number:
var moreThen = from dA in divAssignments
select new { dA.rNI, IndictmentCount = dA.indictmentNumber.Count() };
Most of the examples are dealing with static int[] and don't seem to work in my case.
How do I get a group and then a count? If I could put in a having that would be fantastic.
from a t-sql POV I'd use this:
Select rni, bookingNumber, count(*) IndictmentCount
from divAssignments
group by rni, bookingNumber
having count(*) > 0
TIA
How about something like this:
var query = from item in divAssignments
group item by item.rNI into grouping
select new
{
Id = grouping.Key,
Count = grouping.Count()
}
If you're interested in grouping by both the rNI and the booking number, I would change it to this:
var query = from item in divAssignements
group item by new { item.rNI, a.Booking } into grouping
select new
{
Id = grouping.Key,
Count = grouping.Count
};
OR
var query = from item in divAssignments
group item by item into grouping
select new
{
Id = grouping.Key,
Count = grouping.Count()
}
and implement IEquatable on the divAssignment object to support equality comparison. The other option if you'd like is to write an IEqualityComparer instance to do the composite key comparison. Your query could then look like:
var query =
divAssignments
.GroupBy(i => i, new MyCustomEqualityComparer())
.Select(i => new { Key = i.Key, Count = i.Count());
var query =
from dA in divAssignments
group dA by new { dA.rNI, dA.bookingNumber };
foreach(var grp in query)
{
Console.WriteLine("rNI={0}, bookingNumber={1} => Count={2}", grp.Key.rNI, grp.Key.bookingNumber, grp.Count());
}
If you use a Grouping operator in Linq you will get what you need. The code:
var count = from a in divAssignments
group a by new { a.rNI, a.Booking } into b
select b;
will return a collection of IGrouping objects. This will give you the Key (in my example this will be an anonymous type with an rNI and a Booking property) and a collection of the divAssignments that match the key.
Using Method syntax (much easier to read in my opinion):
First group the records, then select a new result for each group that contains the count.
var groups = divAssignments.GroupBy(d => new { d.rNI, d.Booking });
groups.Select(g=> new { g.Key.rNI, g.Key.Booking, IndictmentCount = g.Count() });

Resources