How to calculate count on of table column using group by clause in linq - asp.net

I'm new to linq.
In c# I'm doing as follows to get the count of one column.
SELECT DispatcherName,
ActivityType,
CONVERT(BIGINT,COUNT(ActivityType)) AS Total
FROM ACTIVITYLOG
GROUP BY DispatcherName,
ActivityType
ORDER BY Total DESC
Can any one tell m,how I can achieve the same thing using LINQ.
Update:
HI I did as follows and got the reslut.
But I'm not able to convert result to datatable.
this is how I did.
here dt is datatabe with two columns Dispatchername and ActivityType.
var query1 = from p in dt.AsEnumerable()
group p by new
{
DispatcherName = p.Field<string>("Dispatchername"),
Activity = p.Field<string>("ActivityType"),
}
into pgroup
let count = pgroup.Count()
orderby count
select new
{
Count = count,
DispatcherName = pgroup.Key.DispatcherName,
Activity = pgroup.Key.Activity
};
pls help me out asap.

from c in ACTIVITYLOG
group c by new {c.DispatcherName, c.ActivityType} into g
orderby g.Count() descending
select new { g.Key.DispatcherName, g.Key.ActivityType, Total = g.Count() }

If you want your results returned back to a DataTable, one option is to use the CopyToDataTable method.
Here's a live example: http://rextester.com/XHX48973
This method basically requires you to create a dummy table in order to use its NewRow method - the only way to create a DataRow, which is required by CopyToDataTable.
var result = dt.AsEnumerable()
.GroupBy(p => new {
DispatcherName = p.Field<string>("DispatcherName"),
Activity = p.Field<string>("ActivityType")})
.Select(p => {
var row = dummy.NewRow();
row["Activity"] = p.Key.Activity;
row["DispatcherName"] = p.Key.DispatcherName;
row["Count"] = p.Count();
return row;
})
.CopyToDataTable();
Perhaps a better way might be just fill in the rows directly, by converting to a List<T> and then using ForEach.
DataTable dummy = new DataTable();
dummy.Columns.Add("DispatcherName",typeof(string));
dummy.Columns.Add("Activity",typeof(string));
dummy.Columns.Add("Count",typeof(int));
dt.AsEnumerable()
.GroupBy(p => new { DispatcherName = p.Field<string>("DispatcherName"),
Activity = p.Field<string>("ActivityType")})
.ToList()
.ForEach(p => {
var row = dummy.NewRow();
row["Activity"] = p.Key.Activity;
row["DispatcherName"] = p.Key.DispatcherName;
row["Count"] = p.Count();
dummy.Rows.Add(row);
});
Live example: http://rextester.com/TFZNEO48009

This should do the trick:
IList<ACTIVITYLOG> allActivityLogs;
var result = (from c in allActivityLogs
select new
{
DispatcherName = c.DispatcherName,
ActivityType = c.ActivityType,
Total = c.ActivityType.Count
}).OrderByDescending(x => x.Total)
.GroupBy(x => new { x.DispatcherName, x.ActivityType });
You only need to substitute the allActivityLogs collection with the actual collection of your entities.

Related

How to assign key and count to two different labels asp.net

I have this query:
var months = dates.GroupBy(
x => x.Value.Month).Select(g => new { Month = g.Key, Count = g.Count()});
lbl1.Text = string.Join(",", months);
How do I assign key and count to two different labels?
Try this
lblMonth.Text=months.Month;
lblCount.Text=months.Count;
Also you have to call FirstOrDefault() or ToList() in order to select data. Currently you code will not select data.
var months = dates.GroupBy(x => x.Value.Month).Select(g => new { Month = g.Key, Count = g.Count() }).FirstOrDefault();
OR
var months = dates.GroupBy(x => x.Value.Month).Select(g => new { Month = g.Key, Count = g.Count() }).ToList();
if you use ToList() than you will have to get values by index like
lblMonth.Text=months[0].Month;
lblCount.Text=months[0].Count;

Linq to Entity, selecting group with or without value

Hi Need some help with LINQ query.
I have entity called Shift. This entity has several value field but the ones I am intressted in are ShiftID (int), ShiftDate (DateTime) and GrossMount (decimal(10,2). And this needs to be grouped by month (binding this to a graph in ASP.NET).
I need data for the last 12 months grouped by month.
I have come a bit on the way with this post: Linq to Entity, selecting group without value but not quite all the way.
This is my code for now:
public IQueryable<Shift> GetPastMonths(int months, string accountNumber)
{
_context = new EtaxiEnteties();
var _date = DateTime.Today;
var _firstOfMonth = new DateTime(_date.Year, _date.Month, 31);
var _twelveMonthAgoFirstOfMonth = _firstOfMonth.AddMonths(-12);
// Generate a collection of the months and years for the last 12 months
var _monthYears = Enumerable.Range(-12, 12).Select(monthOffset => { var monthDate = _firstOfMonth.AddMonths(monthOffset); return new { y = monthDate.Year, m = monthDate.Month }; });
var _data = (from _monthYear in _monthYears
join _i in
(from _i in _context.Shifts.Where(acc => acc.Account.AccountNumber == accountNumber)
where _i.ShiftDate >= _twelveMonthAgoFirstOfMonth && _i.ShiftDate < _firstOfMonth
group _i by new { y = _i.ShiftDate.Year, m = _i.ShiftDate.Month } into g
select new { ShiftID = g.Key, GrossAmount = g.Count() }) on _monthYear equals _i.ShiftID into j
from _k in j.DefaultIfEmpty()
select new Shift() { ShiftDate = new DateTime(_monthYear.y, _monthYear.m, 1), GrossAmount = _k != null ? _k.GrossAmount : 0 });
return _data as IQueryable<Shift>;
}
Now I have in return a collection of Shift objects, grouped by month but still missing the GrossAmount. Althoug i would need this from today date (only getting from 1 of current month).
Believe this is my main problem: GrossAmount = g.Count(), but I am not sure
Any LINQ specialist out there that could give me a push?
Use GrossAmount = g.Sum(x => x.GrossAmount) to calculate total GrossAmount value of grouped Shift entities. I believe you have typo in GrossAmount (GrossMount) property name.

Why is my query not returning distinct rows?

Afternoon,
I am trying to return a list of products from my SQL Server 2008 R2 database but I only want to return the results with the latest date.
However the code below seems to return all items, even the ones with an older date. How do I go about getting my results with just the latest date.
var query = (from a in dc.aboProducts
join t in dc.twProducts on a.sku equals t.sku
join lp in dc.LowestPrices on a.asin equals lp.productAsin
select new GetLowestPrices
{
productAsin = lp.productAsin,
sku = t.sku,
title = t.title,
twprice = Convert.ToString(t.twPrice),
lowprice = Convert.ToString(lp.price),
amzprice = Convert.ToString(lp.tweAmzPrice),
lastupdated = Convert.ToDateTime(lp.priceDate)
}).Distinct().OrderBy(ti => ti.title);
return query.ToList();
Try something like this:
var query =
from a in dc.aboProducts
join t in dc.twProducts on a.sku equals t.sku
join lp in dc.LowestPrices on a.asin equals lp.productAsin
select new GetLowestPrices
{
productAsin = lp.productAsin,
sku = t.sku,
title = t.title,
twprice = Convert.ToString(t.twPrice),
lowprice = Convert.ToString(lp.price),
amzprice = Convert.ToString(lp.tweAmzPrice),
lastupdated = Convert.ToDateTime(lp.priceDate)
};
var lookup =
query
.ToLookup(x => x.sku)
.Select(x => x.OrderByDescending(y => y.lastupdated).First())
.OrderBy(x => x.title);
return lookup.ToList();
Because the Distinct is not applied on the existing list, but create a new one, and you need to get it on a new list as:
val DistinctList = ExistingList.Distinct().ToList();

Group using linq return datatable

i have a linq query that returns Articles ordered by the number of tags that match the current article
e.g
current article has tags - tag1, tag2, tag3
tagged article 1 - tag1,tag2,tag3
tagged article 2 - tag1,tag2
linq i have is
DataTable query = (from row in dt.AsEnumerable()
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
select row).CopyToDataTable();
i want to add the group by ClassName which is the article type (literature, case study, download etc)
so would be
group row by {row.Field<string>("ClassDisplayName")}
however when i add this to the query i get red sqiggles
DataTable query = (from row in dt.AsEnumerable()
group row by {row.Field<string>("ClassDisplayName")}
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
select row).CopyToDataTable();
any ideas what i'm doing wrong?
This is the current one that works with just the order by
DataTable dt = ArticleCollection(SqlClause.ToString());
var seperator = new[] { ",", " " };
var current = dr["Tags"].ToString();
var currenttags = dr.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries);
DataTable query = (from row in dt.AsEnumerable()
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
// group row by row.Field<string>("ClassDisplayName") into g
select row).CopyToDataTable();
if (!DataHelper.DataSourceIsEmpty(query))
{
TagRepeaterOutter.DataSource = query;
TagRepeaterOutter.DataBind();
}
If you are trying to order by count, and within each value of count, group the rows by ClassDisplayName, you can try this:
DataTable query = (from row in dt.AsEnumerable()
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
let displayName = row.Field<string>("ClassDisplayName")
orderby count descending, displayName
select row).CopyToDataTable();
DataTable query = (from row in dt.AsEnumerable()
where (row.Field<string>("ClassDisplayName") == dr["ClassDisplayName"].ToString())
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
select row).CopyToDataTable();
IEnumerable<DataRow> types = (from row in dt.AsEnumerable()
group row by row.Field<string>("ClassDisplayName") into g
select g.FirstOrDefault());
DataTable dtType = types.CopyToDataTable();
and then another query on the inner nested repeater
DataTable query = (from row in dt.AsEnumerable()
where (row.Field<string>("ClassDisplayName") == dr["ClassDisplayName"].ToString())
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
select row).CopyToDataTable();
anyone have a better solution let me know

how group by in Linq with 2 Field?

how group by in Linq with 2 Field ?
(from i in info
group i by i.OrderId into g
select new { orderId = g.Key, infos = g });
not only order by with order Id but with two field like ...
group by i.orderId And i.City
how this will do?
I believe you want something like this:
var result = from i in info
group i by new { OrderId = i.OrderId, City = i.City } into g
select new { OrderId = g.Key, Infos = g };
Creating the key as an anonymous type simply allows LINQ to use the default equality comparers for all the fields of the anonymous type, which should do the job in most situations.
As a follow-up to Noldorin's answer, you can omit the field names on the anonymous type when they match the fields you're setting them to.
Example:
var result = from i in info
group i by new { i.OrderId, i.City } into g
select new { OrderId = g.Key, Infos = g };
Another follow-up to the Noldorin's and Josh Einstein's answers...OrderID will take on the entire key...which in this case is a new object with two properties, OrderID and City. If your final result set needs the OrderID to be the OrderID, then you'll need to do the following:
var result = from i in info
group i by new { i.OrderId, i.City } into g
select new { OrderId = g.Key.OrderId, Infos = g };

Resources