how group by in Linq with 2 Field? - asp.net

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

Related

select more column not in group by using linq in c#

cmd = new SqlCommand(" ", con);
da = new SqlDataAdapter(cmd);
DataTable t_eight = new DataTable("t_eight");
da.Fill(t_eight); //databale "t_eight" fill
//linq query
var query3 = (from a in t_eight.AsEnumerable() //t_eigth Databale
group a by new
{ //Group by with condition
IdendityName = a.Field<String>("Idendity Name"),
ContactPersonName = a.Field<String>("Contact Person Name"),
CustomerName = a.Field<String>("Customer Name")
}
into g
select new
{
IdendinyName = g.Key.IdendityName,
ContactPersonName = g.Key.ContactPersonName,
CurtomerName = g.Key.CustomerName,
TotalBook = g.Sum(x => x.Field<Int32>("Total Book Quantity")
+ x.Field<Int32>("Quatan Book Qty")
- x.Field<Int32>("Return Book Quality"))
});
GridView1.DataSource = query3;
GridView1.DataBind();
Datatable contains columns Identity Name, customer Name, customer Contact Name, Total Book Quantity, Return Book Quality, and Quatan Book Qty.
Group by contains three column Identity Name, customer Name, and customer Contact Name
New column in select statement Total Book contains ( total book quant+Quatan Book Qty-Return Book Quality). I want all columns in the gridview but the grid contains Identity Name, customer Name, customer Contact Name, and total book columns
How can I do this?
Dataset table "t_eight"
Gridview missing column Quatan Book and Return Book
Assuming you expect the additional fields to be identical once the rows are grouped, you just need to pick a random row from the group to get the values - the First row should work.
var query3 = (from a in t_eight.AsEnumerable()//t_eigth Databale
group a by new
{//Group by with condition
IdendityName = a.Field<String>("Idendity Name"),
ContactPersonName = a.Field<String>("Contact Person Name"),
CustomerName = a.Field<String>("Customer Name")
}
into g
select new {
g.Key.IdendityName,
g.Key.ContactPersonName,
g.Key.CustomerName,
ReturnBookQuality = g.First().Field<Int32>("Return Book Quality"),
QuatanBookQty = g.First().Field<Int32>("Quatan Book Qty"),
TotalBook = g.Sum(x => x.Field<Int32>("Total Book Quantity")
+ x.Field<Int32>("Quatan Book Qty") - x.Field<Int32>("Return Book Quality"))
}
);
Note: I removed the redundant member names from the anonymous type, I don't see any reason to put them there.
If I understand you correctly, you want to see the totals of three columns besides the calculated TotalBook column. Here's how you can do that:
var query3 = (from a in t_eight.AsEnumerable()
group a by new
{
IdendityName = a.Field<String>("Idendity Name"),
ContactPersonName = a.Field<String>("Contact Person Name"),
CustomerName = a.Field<String>("Customer Name")
}
into g
let tbq = g.Sum(x => x.Field<Int32>("Total Book Quantity"))
let qbq = g.Sum(x => x.Field<Int32>("Quatan Book Qty"))
let rbq = g.Sum(x => x.Field<Int32>("Return Book Quality"))
select new
{
IdendinyName = g.Key.IdendityName,
ContactPersonName = g.Key.ContactPersonName,
CurtomerName = g.Key.CustomerName,
TotalBookQuantity = tbq,
QuatanBookQuantity = qbq,
ReturnBookQuantity = rbq,
TotalBook = tbq + qbq - rbq
});
The three let statements collect the individual sums per grouping, after which you can use the variables tbq etc. multiple times.

is there a way to get rid of DTO

I am using Entity Framework. I have the following query in which I get data using two tables Application and Employee connected by a foreign key EmployeeID in Application Table. The tables have 1-1 relationship .
Is there a way to simplify the following code and get rid of the DTO Employee1
which is the same as auto generated Employee class
public List<Employee1> GetApplicant(int ApplicationID)
{
var context = new FPSDB_newEntities();
var data = (from a in context.Applications
join e in context.Employees on a.EmployeeID equals e.EmployeeID
where
(
a.ApplicationID == ApplicationID
)
select new Employee1
{
EmployeeID = e.EmployeeID,
SecondEmail = e.SecondEmail,
EmailID = e.EmailID,
Title = e.Title,
Name = e.Name,
Rank = e.Rank,
POBox = e.POBox,
Phone = e.Phone,
JoinDate = e.JoinDate,
Status = e.Status,
DepartmentID = e.DepartmentID.Value,
NameString = e.NameString,
Department = e.Department,
ParentDept = e.ParentDept,
DepartmentAr = e.DepartmentAr,
NameAr = e.NameAr,
NameStringAr = e.NameStringAr,
TitleAr = e.TitleAr
}).ToList();
return data;
}
If you need to return list of Employees, just select e which refers to Employee and don't use Employee1 as a DTO.
public List<Employee> GetApplicant(int ApplicationID)
{
var context = new FPSDB_newEntities();
var data = (from a in context.Applications
join e in context.Employees on a.EmployeeID equals e.EmployeeID
where
(
a.ApplicationID == ApplicationID
)
select e).ToList();
return data;
}
Another way is this, which I would prefer because of readability:
public List<Employee> GetApplicant(int ApplicationID)
{
var context = new FPSDB_newEntities();
var data = context.Applications.Where(p=>p.ApplicationID == ApplicationID).Select(p=>p.Employee).ToList();
return data;
}

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.

How to calculate count on of table column using group by clause in linq

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.

linq query with group

I'm having a table which contains userId, regBy, regDate and so many..
I need a out of regDate, regBy and count(userId).
How can a query this using LINQ..
From what I understand, you want to group by two fields, regDate and regBy. In that case, the select statement looks something like this:
var myQuery = from User myUser in myContext.Users
group myUser by new { regDate = myUser.regDate , regBy = myUser.regBy } into g
select new
{
regDate = g.Key.regDate,
regBy = g.Key.regBy,
Count = g.Count()
};

Resources