I have a following list of documents:
List<DocumentInfo> list1 = new List<DocumentInfo>()
{
new DocumentInfo { Name = "Customer1", DocCount = 5 },
new DocumentInfo { Name = "Customer1", DocCount = 10 },
new DocumentInfo { Name = "Customer1", DocCount = 5 },
new DocumentInfo { Name = "Customer2", DocCount = 4 },
new DocumentInfo { Name = "Customer2", DocCount = 6 },
new DocumentInfo { Name = "Customer3", DocCount = 3 }
};
How to group the above list based on 'Name' and sum of 'DocCount' using Linq and store in another list? I want something like following:
Name = "Customer1", DocCount = 20
Name = "Customer2", DocCount = 10
Name = "Customer3", DocCount = 3
var results = list1.GroupBy(i => i.Name)
.Select(g => new
{
Name = g.Key,
DocCount = g.Sum(i => i.DocCount)
});
var list2 = list1.GroupBy(x => x.Name).Select(g => new DocumentInfo()
{
Name = g.Key,
DocCount = g.Sum(x => x.DocCount)
});
Try this:
list1.GroupBy(di => di.Name).Select(g => new DocumentInfo {Name = g.Key, DocCount = g.Sum(dc => dc.DocCount)});
var result= from item in list1
group item by item.Name
into g
select g;
var groupedInfo = result.SelectMany(group => group);
foreach(var g in groupedInfo)
{
//Do Summation
}
Try like this;
var anotherlist = list1.GroupBy(g => g.Name)
.Select(s => new
{
Name = s.Key,
DocCount = s.Sum(i => i.DocCount)
});
It is simply, getting sum of DocCount and their Name properties by grouping based Name.
Here is another way to do the same
var sumOfDocs = from doc in list1 group doc by doc.Name into g
select new { DocName = g.Key, DocSum = g.Sum(i => i.DocCount) };
Related
I'm trying to format a double value (by showing only 2 decimals). I tried to use AsEnumerable but I keep getting this error
LINQ to Entities does not recognize the method
String.Format
var tw = workers.Select(x => new
{
Id = x.Id,
JobOpportunityFeedbacks = x.JobOpportunityFeedbacks.AsEnumerable().
Select(y => new
{
Rating = String.Format("0.00",y.Rating),
Feedback = y.Feedback
});
You have to do the AsEnumerable outside of your initial Select
var tw = workers.Select(x => new
{
Id = x.Id,
JobOpportunityFeedbacks = x.JobOpportunityFeedbacks
.Select(y => new
{
y.Rating,
y.Feedback
})
})
.AsEnumerable()
.Select(x => new
{
x.Id,
JopOpertunityFeedbacks = x.JobOpportunityFeedbacks
.Select(y => new
{
Rating = String.Format("0.00",y.Rating),
y.Feedback
})
});
Use SqlFunctions class - I didn't try this but should work.
var tw = workers.Select(x => new
{
Id = x.Id,
JobOpportunityFeedbacks = x.JobOpportunityFeedbacks.AsEnumerable().
Select(y => new
{
Rating = SqlFunctions.StringConvert(y.Rating, 4, 2)
Feedback = y.Feedback
});
https://msdn.microsoft.com/en-us/library/dd487158(v=vs.110).aspx
My EF query is supposed to be sorting by the date of the first Product in the list, but for some reason, it only sorts most of the products and some of the dates are in the wrong order.
Here's the code...
using (var context = new SalesEntities())
{
var groupedData = context.s84_Schedule.AsExpandable()
.Where(predicate)
.GroupBy(c => new { c.CustomerID, c.s84_Customer.CustomerName, c.SubdivisionID, c.s84_Subdivision.SubdivisionName, c.LotNumber })
.Select(grouped => new s84_Report_Project_POCO
{
CustomerID = grouped.Key.CustomerID,
CustomerName = grouped.Key.CustomerName,
SubdivisionID = grouped.Key.SubdivisionID,
SubdivisionName = grouped.Key.SubdivisionName,
LotNumber = grouped.Key.LotNumber,
Products = grouped.Select(x => new s84_Report_Project_Product
{
ProductID = x.ProductID,
ProductName = x.s84_Product.ProductName,
ProductDate = x.CustomerExpectedDate,
FieldRepID = x.FieldRepID,
FieldRepName = x.s84_FieldRep.FieldRepName,
InstallerID = x.InstallerID,
InstallerName = x.s84_Installer.InstallerName,
StatusID = x.StatusID,
StatusColor = x.s84_Status.StatusColor,
StatusName = x.s84_Status.StatusName,
Completed = x.Completed
}).ToList()
});
var finalList = groupedData.ToList().Where(x => x.Products.Last().Completed == false).ToList();
List<s84_Report_Project_POCO> lst = finalList.OrderBy(x => x.Products.First().ProductDate).ToList();
return lst;
}
Code seems good to me, but look at how one of the dates is out of order...
weird sorting http://www.84sales.com/weird_sort.png
Try doing the order by on the inital select
var groupedData = context.s84_Schedule.AsExpandable()
.Where(predicate)
.GroupBy(c => new { c.CustomerID,
c.s84_Customer.CustomerName,
c.SubdivisionID,
c.s84_Subdivision.SubdivisionName,
c.LotNumber })
.Select(grouped => new s84_Report_Project_POCO
{
CustomerID = grouped.Key.CustomerID,
CustomerName = grouped.Key.CustomerName,
SubdivisionID = grouped.Key.SubdivisionID,
SubdivisionName = grouped.Key.SubdivisionName,
LotNumber = grouped.Key.LotNumber,
Products = grouped
.Select(x => new s84_Report_Project_Product
{
ProductID = x.ProductID,
ProductName = x.s84_Product.ProductName,
ProductDate = x.CustomerExpectedDate,
FieldRepID = x.FieldRepID,
FieldRepName = x.s84_FieldRep.FieldRepName,
InstallerID = x.InstallerID,
InstallerName = x.s84_Installer.InstallerName,
StatusID = x.StatusID,
StatusColor = x.s84_Status.StatusColor,
StatusName = x.s84_Status.StatusName,
Completed = x.Completed
}).OrderBy(x => x.CustomerExpectedDate).ToList()
});
The problem is the .First() function, witch returns the first record, but not necessarly in date order. if you wich to order your grouped datas by date so that the First() function returns the most recent date, you'll need to order your datas before grouping them, and then REorder your results with the First()function :
using (var context = PrimaryConnection.returnNewConnection())
{
var groupedData = context.s84_Schedule.AsExpandable()
.Where(predicate)
.GroupBy(c => new { c.CustomerID, c.s84_Customer.CustomerName, c.SubdivisionID, c.s84_Subdivision.SubdivisionName, c.LotNumber })
.Select(grouped => new s84_Report_Project_POCO
{
CustomerID = grouped.Key.CustomerID,
CustomerName = grouped.Key.CustomerName,
SubdivisionID = grouped.Key.SubdivisionID,
SubdivisionName = grouped.Key.SubdivisionName,
LotNumber = grouped.Key.LotNumber,
Products = grouped
.Select(x => new s84_Report_Project_Product
{
ProductID = x.ProductID,
ProductName = x.s84_Product.ProductName,
ProductDate = x.CustomerExpectedDate,
FieldRepID = x.FieldRepID,
FieldRepName = x.s84_FieldRep.FieldRepName,
InstallerID = x.InstallerID,
InstallerName = x.s84_Installer.InstallerName,
StatusID = x.StatusID,
StatusColor = x.s84_Status.StatusColor,
StatusName = x.s84_Status.StatusName,
Completed = x.Completed
}).Orderby(t => t.CustomerExpectedDate).ToList()
});
var finalList = groupedData.ToList().Where(x => x.Products.Last().Completed == false).ToList();
List<s84_Report_Project_POCO> lst = finalList.OrderBy(x => x.Products.First().ProductDate).ToList();
All SQL queries (and hence Linq queries, when attached to a SQL database) have a random order, unless you sort them.
Products is not sorted - hence it has a random order.
You sort by Products.First(), but Products has a random order, so your sort will also be random.
Make sure Products is sorted within the query, and you should be ok.
Products = grouped.Select(....)
.OrderBy(x => x.ProductDate)
.ToList()
var approverlist = _db.ApprvRejClaimTravelCashByApproverIdIPhone(ProjectSession.CompanyUserId, ProjectSession.CompanyId, Status).AsEnumerable().ToList();`
var results =
from item in approverlist
group item by item.ClaimId
into g
select new
{
ClaimId = g.Key,
Name = g.First().Name,
Amount = g.Sum(s => s.Amount),
Description = g.First().Description,
Status = g.First().Status,
CreatedDate = g.First().CreatedDate,
SubmitedDate = g.First().SubmitedDate,
FullName = g.First().FullName,
ApproverStatus = g.First().ApproverStatus,
CurrencySymbol = g.First().CurrencySymbol,
chkbox = g.First().chkbox,
IsHierarchy = g.First().IsHierarchy,
ColumnCategory = g.First().ColumnCategory,
ColumnCategoryCode = g.First().ColumnCategoryCode
};
return Json(results.ToDataSourceResult(request));
getting undefined in column Amount when i bind this result to my kendo mvc grid,,,,any one have idea why this happens ?
Also tried below one but same result undefined :
var results = from x in approverlist
group x.ClaimId by new { x.ClaimId, x.Name, x.Description, x.Status, x.CreatedDate, x.SubmitedDate, x.FullName, x.ApproverStatus, x.CurrencySymbol, x.chkbox, x.IsHierarchy, x.ColumnCategory, x.ColumnCategoryCode }
into g
select new { g.Key.ClaimId, g.Key.Name, Amount = g.Sum(), g.Key.Description, g.Key.Status, g.Key.CreatedDate, g.Key.SubmitedDate, g.Key.FullName, g.Key.ApproverStatus, g.Key.CurrencySymbol, g.Key.chkbox, g.Key.IsHierarchy, g.Key.ColumnCategory, g.Key.ColumnCategoryCode };
How do I find the average salary for each department?
var employees = new List<Employee>
{
new Employee {Name = "Tom", Age = 32,Department = "Design",Salary=120000},
new Employee {Name = "John", Age = 22,Department = "UI",Salary=86000},
new Employee {Name = "Sandra", Age = 36,Department = "UI",Salary=83000},
new Employee {Name = "Julie", Age = 54,Department = "Javascript",Salary=80000},
new Employee {Name = "Samantha", Age = 21,Department = "Design",Salary=125000}
};
var massagedEmployees = employees.GroupBy(e => e.Department).Select(g=>g.??????
In SQL I would do something like
select Department,avg(salary) from Employees group by Department
You can use:
var massagedEmployees = employees.GroupBy(e => e.Department)
.Select(g => new { Department = g.Key, Avg = g.Average(e => e.Salary) } );
var massagedEmployees = employees.GroupBy(e => e.Department)
.Select(g=>g.Average(x=>x.Salary));
You should include the Department key like this:
var massagedEmployees = employees.GroupBy(e => e.Department)
.Select(g=>
new {
Department = g.Key,
SalaryAvg = g.Average(x=>x.Salary)
});
var massagedEmployees = employees
.GroupBy(e => e.Department)
.Select(p=> new {p.Key, p.Average(q=>q.Salary)};
employees.Where(e => e.Department == "[department]")
.Average(e => e.Salary);
var massagedEmployees =
employees.GroupBy(e => e.Department).Select(c => new {Dep = c.Key, Sum = c.Sum(i => i.Salary)/c.Count()});
Actually you can simplify it to a single operator unlike the previous GroupBy answers GroupBy has an overload just for that so that you don't need the following select:
employees.GroupBy(e=>e.Department,items=>items.Average(e=>e.Salary))
I've got the code below:
var catRoots = CatalogContext.CatalogRoots.Where(cr => cr.Visible);
var catChapter = CatalogContext.CatalogChapters.Where(cch => cch.Visible);
var catThemes = CatalogContext.CatalogThemes.Where(cth => cth.Visible);
var catCompanies = CatalogContext.CatalogCompanies.Where(cc => cc.Visible);
var catRelations = CatalogContext.CatalogCompanyThemeRelations.Where(cctr => cctr.Visible && cctr.OwnerVisible);
var regions = CatalogContext.Regions.AsQueryable();
var compChapters = catRelations.Where(cctr => cctr.Location == CatalogCompanyLocations.Chapter)
.Join(catChapter, cctr => cctr.ParentID, cch => cch.ID, (cctr, cch) => new { Relation = cctr, Chapter = cch })
.Join(catRoots, cch => cch.Chapter.CatalogRootID, cr => cr.ID, (cch, cr) => new { CatalogRoot = cr, CatalogChapter = cch.Chapter, CatalogRelation = cch.Relation })
.Join(catCompanies, cr => cr.CatalogRelation.CompanyID, cc => cc.ID, (cr, cc) => new { Root = cr.CatalogRoot, Chapter = cr.CatalogChapter, Theme = default(CatalogTheme), Company = cc })
.Join(regions, cc => cc.Company.RegionID, r => r.ID, (cc, r) => new { Root = cc.Root, Chapter = cc.Chapter, Theme = cc.Theme, Company = cc })
.GroupBy(gr => new { Chapter = gr.Chapter, Name = gr.Root.Name, ID = gr.Root.ID, Icon = gr.Root.Icon, Rewrite = gr.Root.Rewrite, Sort = gr.Root.Sort })
.Select(gr => new { Chapter = gr.Key.Chapter, ID = gr.Key.ID, Name = gr.Key.Name, Icon = gr.Key.Icon, Rewrite = gr.Key.Rewrite, Sort = gr.Key.Sort, Count = gr.Count() });
var compThemes = catRelations.Where(cctr => cctr.Location == CatalogCompanyLocations.Theme)
.Join(catThemes, cctr => cctr.ParentID, cth => cth.ID, (cctr, cth) => new { Relation = cctr, Theme = cth })
.Join(catChapter, cth => cth.Theme.CatalogChapterID, cch => cch.ID, (cth, cch) => new { Relation = cth.Relation, Theme = cth.Theme, Chapter = cch })
.Join(catRoots, cch => cch.Chapter.CatalogRootID, cr => cr.ID, (cch, cr) => new { Relation = cch.Relation, Theme = cch.Theme, Chapter = cch.Chapter, Root = cr })
.Join(catCompanies, cr => cr.Relation.CompanyID, cc => cc.ID, (cr, cc) => new { Root = cr.Root, Chapter = cr.Chapter, Theme = cr.Theme, Company = cc })
.Join(regions, cc => cc.Company.RegionID, r => r.ID, (cc, r) => new { Root = cc.Root, Chapter = cc.Chapter, Theme = cc.Theme, Company = cc.Company })
.GroupBy(gr => new { Chapter = gr.Chapter, Name = gr.Root.Name, ID = gr.Root.ID, Icon = gr.Root.Icon, Rewrite = gr.Root.Rewrite, Sort = gr.Root.Sort })
.Select(gr => new { Chapter = gr.Key.Chapter, ID = gr.Key.ID, Name = gr.Key.Name, Icon = gr.Key.Icon, Rewrite = gr.Key.Rewrite, Sort = gr.Key.Sort, Count = gr.Count() });
var source = compChapters.Union(compThemes);
var chapters = source.Select(r => new { Chapter = r.Chapter, Count = r.Count }).Cast<object>().Distinct();
public static Func<DataContext, IQueryable<object>, IEnumerable<object>> filteredFunc =
CompiledQuery.Compile<DataContext, IQueryable<object>, IEnumerable<object>>
(
(DataContext db, IQueryable<object> q) => q.Distinct().ToList()
);
filtredChapters = filteredFunc(CatalogContext, chapters);
I'm getting an error "parameteres cannot be sequences" when I run filteredFunc, which is weird, because "chapters" object is IQueryable, not IEnumerable, so why am I getting the error?
The code below works fine, but it is not good for me.
filtredChapters = chapters.Distinct().Cast<object>().ToList();
You cannot use compiled queries with an IEnumerable like this. The number of items in the enumeration can vary and so the query plan for the query will vary based on its size. Just remove the compiled query and use the function as is.