C# LinqToExcel, Distinct showing all results - tried online solutions, couldn't solve - c#

var ItemMaster = new ExcelQueryFactory("E:\\Group Item Master.xlsx");
var ItemList = (from x in ItemMaster.Worksheet()
select new
{
CategoryName = x["CategoryName"],
GroupName = x["GroupName"],
ModelNo = x["ModelNo"],
Description = x["Description"],
Code = x["Code"]
}).ToList();
var DistinctCategory = ItemList.Select(x => x.CategoryName).ToArray().Distinct();
//shows categoryname repeated
var iteml = ItemList.GroupBy(x => x.CategoryName);
var DistinctCategoryTwo = iteml.Select(x => x.First()).ToList();
//shows categoryname repeated

Sorry guys, it was linqToExcel specific issue
var CategoryList = ItemList.Select(x => x.CategoryName.Value).Distinct().ToList();
value column was needed to fix it

Related

Return children and subchildren withouth having sub-array Linq

I have a linq query that returns users/employees with their corresponding supervisors.
List<OrgChartViewModel> OrgChart = new List<OrgChartViewModel>();
var userlist = (from u in users
select new OrgChartViewModel
{
id = u?.id.ToString(),
pid = u?.pid.ToString(),
name = u?.name,
title = u?.title,
img = u?.img
}).OrderBy(x => x.name).ToList();
OrgChart.AddRange(userlist);
return Json(OrgChart.DistinctBy(x => x.id));
However, I need a query that returns the supervisor and their children along with their sub-children without having a sub-array/nested array.
What I have tried :
List<OrgChartViewModel> OrgChart = new List<OrgChartViewModel>();
var userlist = (from u in users
select new OrgChartViewModel
{
id = u?.id.ToString(),
pid = u?.pid.ToString(),
name = u?.name,
title = u?.title,
img = u?.img
}).OrderBy(x => x.name).ToList();
OrgChart.AddRange(userlist);
foreach (var ul in userlist)
{
var userlist2 = (from u in users
select new OrgChartViewModel
{
id = u?.id.ToString(),
pid = u?.pid.ToString(),
name = u?.name,
title = u?.title,
img = u?.img
}).Where(x => x.pid == ul.id).OrderBy(x => x.name).ToList();
OrgChart.AddRange(userlist2);
}
return Json(OrgChart.DistinctBy(x => x.id));
But this only returns the first layer of sub-children. What I want to achieve is to return unlimited layers of sub-children without having sub-arrays.

LINQ group by List<results> and return results

I have Three List<Results>
var list1 = new List<Results> {
new Results{ Empid = 1,Empname = "John",Rating = 1.33},
new Results{ Empid = 2,Empname = "Aarya",Rating = 1.6},
new Results{ Empid = 3,Empname = "Sansa",Rating = 1.6}
};
var list2 = new List<Results> {
new Results{ Empid = 1,Empname = "John",Rating = 2.33},
new Results{ Empid = 2,Empname = "Aarya",Rating = 2.6},
new Results{ Empid = 3,Empname = "Sansa",Rating = 1.6}
};
var list3 = new List<Results> {
new Results{ Empid = 1,Empname = "John",Rating = 0.33},
new Results{ Empid = 2,Empname = "Aarya",Rating = 0.6}
};
I want final result like(sum of all ratings based on Empid)
Final={Empid=1,Empname="John",Rating=3.99}
{Empid=2,Empname="Aarya",Rating=4.8}
{Empid=3,Empname="Sansa",Rating=3.2}
How to achieve this by using Linq, I am new to LinQ i am trying using GroupBy but I couldn't.
Use Concat to merge the lists and then a normal group by:
var result = list1.Concat(list2).Concat(list3)
.GroupBy(item => new { item.Empid, item.Empname }, item => item.Rating)
.Select(g => new {
Id = g.Key.Empid,
Name = g.Key.Empname,
Rating = g.Sum() });
Or in query syntax:
var result = from item in list1.Concat(list2).Concat(list3)
group item.Rating by new { item.Empid, item.Empname } into g
select new {
Id = g.Key.Empid,
Name = g.Key.Empname,
Rating = g.Sum()
};
sum of all ratings based on Empid - Note that if the id and name correlate then it is simplest to group by the two of them as in the example above. Otherwise, group by id and retrieve for each group the .First().Empname
first you should concat all lists together and then write something like this:
var q = from p in concatlist
group p by new { p.Empid, p.Empname} into g
select new
{
Empid = g.Key.Empid,
Empname = g.Key.Empname,
Rating = g.Sum(c=>c.Rating)
};
Or you can use Enumerable.SelectMany method to "flatten" lists and then use same grouping as in other answers
var final =
new[] { list1, list2, list3 }.SelectMany(list => list)
.GroupBy(result => new { result.EmpId, result.EmpName })
.Select(group => new Results
{
EmpId = group.Key.EmpId,
EmpName = group.Key.EmpName,
Rating = group.Sum(result => result.Rating)
});
With SelectMany you will be able to query dynamic amount of lists

Linq query rewriting

This has really stumped me...
I have two queries..
This one does NOT work, with the error,
"LINQ to Entities does not recognize the method GetAllCustomers()' method, and this method cannot be translated into a store expression."
results = theDocuments.Select(x => new DocumentModel()
{
document_id = x.document_id,
document_type = x.document_type,
franchisee_id = x.franchisee_id,
customer_id = x.customer_id,
address = x.address,
area_id = x.area_id,
***HERE***customer_name = outletService.GetAllCustomers().Where(xx => xx.id == x.customer_id).First().name
}).OrderBy(x => x.document_id);
Now rewriting it like this works:
results = from p in theDocuments
join cust in outletService.GetAllCustomers() on p.customer_id equals cust.id
select new DocumentModel()
{
customer_name = cust.name,
document_id = p.document_id,
document_type = p.document_type,
franchisee_id = p.franchisee_id,
customer_id = p.customer_id,
address = p.address
};
I understand that this cannot be converted to it's relevant SQL, however, I am not sure what the second query is doing differently in it's execution in order for it to work, does it execute the GetAllCustomers() before doing anything else? How is it working differently internally?
How could I rewrite the first query so that it executes correctly?
Thanks,
James.
**This is what I ended up with **
results = theDocuments.Join(
outletService.GetAllCustomers(), docs => docs.customer_id, customers => customers.id, (doc, cust) => new DocumentModel()
{
document_id = doc.document_id,
document_type = doc.document_type,
franchisee_id = doc.franchisee_id,
customer_id = doc.customer_id,
address = doc.address,
area_id = doc.area_id,
customer_name = cust.name
});
The first one try to translate your method into a SQL method, the second create a join in the query. In my opinion the correct way is using join :)
I was a problem. I found a solution. That might be help you.
dynamic user = new
{
Name = "",
Surname = ""
};
dynamic userModel = new
{
Name = "",
Surname = "",
FullName = ""
};
var query = db.User.AsNoTracking();
query = query.Select(x => new userModel
{
Name = x.Name,
Surname = x.SurName,
FullName = $"{x.Name}{x.SurName}",
}).ToList();
If you try to execute this query. You will take a crash. Linq doesnt support
FullName = $"{x.Name}{x.SurName}"
You have to change this line to
FullName = x.Name + " " + x.SurName

C#, JSON: Join two array to use JSON

Can you help me to resolve this proplem. I will use JSON with Name and Description and want to merge two array.
var listCateogries = categories.Select(x => new
{
Name = x.Name,
Description = x.Description
});
var listProducts = products.Select(x => new
{
Name = x.Name,
Description = x.Details
});
var data = listCateogries + listProducts;
Thanks you very much.
Try Enumerable.Concat
var data = listCateogries.Concat(listProducts);

C# LINQ filtering

I have this piece of code
var tblGrouped = dtCSV.AsEnumerable()
.GroupBy(r => new
{
product_id = r.Field<String>("product_id"),
owner_org_id = r.Field<String>("owner_org_id"),
});
But I want to add an additional column to filter by. Basically if course_type_id = 1 for example. dtCSV is the source where the course_type_id is populated. I tried the following but it didn't work:
var tblGrouped = dtCSV.AsEnumerable()
.GroupBy(r => new
{
product_id = r.Field<String>("product_id"),
owner_org_id = r.Field<String>("owner_org_id"),
course_type_id = "1",
});
If I understand your requirement correctly, you want to group rows which have a course_type_id of 1?
var tblGrouped = dtCSV.AsEnumerable()
.Where(r => r.Field<String>("course_type_id") == "1")
.GroupBy(r => new
{
product_id = r.Field<String>("product_id"),
owner_org_id = r.Field<String>("owner_org_id"),
});
To filter by use Where syntax
Ex. .Where(a=>a.Field<String>("course_type_id") == "1")
You'll want to add the condition first. You can do that using .Where:
var tblGrouped = dtCSV.AsEnumerable()
.Where(r => r.Field<String>("course_type_id") == "1")
.GroupBy(r => new
{
product_id = r.Field<String>("product_id"),
owner_org_id = r.Field<String>("owner_org_id"),
course_type_id = "1"
});

Categories