Linq extract a count() value from a data object - linq

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

Related

Linq and group by clause

I am curious what the x is for in a a linq group by clause: group x by ...
The x can be replaced by an 1:
var query = from box in c.Boxes
join item in c.Items on box equals item.Box
group 1 by new { BoxId = box.BoxId, item.ItemType.ItemTypeId } into g
select new { g.Key.BoxId, g.Key.ItemTypeId, Count = g.Count() };
Does anybody have a sample where the x (or wathever local variable you chose in the group by ) is really of some value?
I mean
var query2 = from box in c.Boxes
group box by box.BoxId into q
select q.Key;
can be replaced by
var query2 = from box in c.Boxes
group 1 by box.BoxId into q
select q.Key;
That's the expression that determines what will go in the output of the group by clause.
You are actually not inspecting the whole output, but only the Keys, which are the same in the examples above, because the grouping is done by the same thing (box.BoxId).
However, replace the last line:
select q.Key;
with
select q;
You will notice that:
the group 1 by ... query will return an IGrouping<int, int> which will have all values set to 1
the group box by ... query will return an IGrouping<int, Box>, which will have all the boxId keys and, for each of them, the corresponding Box objects with respect to the grouping criteria.
In group x by... the x is what gets aggregated.
So you could write something like
var childrenByAge = from child in class
group getName(child) by child.Age;
This gives you a grouping containing names of children for each age.
Here is a simple example where you can test the difference easily:
static void Main(string[] args)
{
var grouping = from c in "Hello World!"
group c by c; // Replace 'group c by' with 'group 1 by'
// and compare results
foreach (var group in grouping)
{
Console.Write("KEY: {0} VALUES :", group.Key);
foreach (var value in group)
Console.Write(" {0}", value);
Console.WriteLine();
}
Console.ReadKey();
}

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

Group by Linq . Count of Key field

select
count(di.field1) as myCount,
di.field2
from di
group by di.field2
Im trying to understand the concept of this :
group di.field2 by new { di.field1, di.field2 } into g
select new
{
documentID = g.Key.field2,
docCount = g.Count(????)
});
How do i get the value of the field1 count ?
Perhaps something like this:
group di by di.field2 into g
select new
{
documentID = g.Key,
docCount = g.Select(c => c.field1).Count()
});
from p in di
group p by p.field2 into g
select new { field2 = g.Key, field2Count = g.Count() };
Check this., This should work
Do you need to do the grouping to get the field count? Can't you just do:
var count=di.field1.Count;

Linq grouping and projection query

I have a EF "Call" class which has a date, telephone number, caller name, and call cost.
My aim is to group the calls by the telephone number, and sum the total cost, and take the results of the 40 most expensive calls. I have all of this working, but I am having trouble with the projection, how do I get access to caller name?
var query =
(
from call in model.Calls
group call by call.TelephoneNumber into g
orderby g.Sum(gr => gr.ActualCost) descending
select new
{
TelephoneNumber = g.Key,
CallerName = ???
Cost = (g.Sum(gr => gr.ActualCost)),
TotalNumbers = g.Count(),
}
).Take(40);
You need group on the CallerName also:
var query =
(from call in model.Calls
group call by new { call.TelephoneNumber, call.CallerName } into g
orderby g.Sum(gr => gr.ActualCost) descending
select new
{
TelephoneNumber = g.Key.TelephoneNumber,
CallerName = g.Key.CallerName,
Cost = (g.Sum(gr => gr.ActualCost)),
TotalNumbers = g.Count(),
}).Take(40);

having and conditional count() in linq query

I want to create this query:
select Something, count(Something) as "Num_Of_Times"
from tbl_results
group by Something
having count(Something)>5
I started with this:
tempResults.GroupBy(dataRow => dataRow.Field<string>("Something"))
.Count() //(.......what comes here , to make Count()>5?)
from item in tbl_results
group item by item.Something into groupedItems
let count = groupedItems.Count()
where count > 5
select new { Something = groupedItems.Key, Num_Of_Times = count };
UPDATE : This would give you the result as an IQueryable<DataRow> :
DataTable dt= new DataTable();
dt.Columns.Add("Something", typeof(int));
dt.Columns.Add("Num_Of_Times", typeof(int));
var results = (from item in tbl_results
group item by item.Something into groupedItems
let count = groupedItems.Count()
where count > 2
select dt.Rows.Add(groupedItems.Key, count)).AsQueryable();
(note that it also fills the dt table)

Resources