Linq Grouping Question - linq

I'm trying to group by categories;
let's say that I have two tables named as follows:
Products, ProductTypes
var foo = (from products in context.PRODUCTS
join producttype in context.PRODUCTTYPE
group producttype by new {producttype.name, producttype.producttypeid, products.productid} into g
select new
{
ProductName = g.Key.name,
ProductID = g.Key.producttypeid,
NumItems = g.Distinct().Count()
});
Here's sample data
Product (productId, Name, ProductTypeID)
-------
1 ProductA 1
2 ProductB 1
3 ProductC 2
4 ProductD 3
ProductType (ProductTypeID, Name)
-----------
1 CategoryA
2 CategoryB
3 CategoryC
ProductSubType (ProductSubtypeID, Name, ProductID)
--------------
1 ProductSubType1 1
2 ProductSubType2 1
3 ProductSubType3 2
4 ProductSubType4 2
5 ProductSubType5 2
6 ProductSubType6 2
7 ProductSubType7 3
my results are as follows
CategoryA 1
CategoryA 1
CategoryB 1
CategoryC 1
I'm expecting the results to be
CategoryA 2
CategoryB 1
CategoryC 1
This is correct, except CategoryA should show up as CategoryA 2.
I'm not sure what simple syntax I'm missing here?
Thanks in Advance.

You are currently grouping by a composite key (name, producttypeid, productid) - any unique combination of these will show up as a separate group. It sounds like you want to group by just producttypeid.
Edit:
First of all your LINQ query seems to be missing a part (the join criteria), it should be more like this to even compile:
var results = (from products in Products
join productType in ProductTypes
on products.ProductTypeID equals productType.ProductTypeId
group productType by new { productType.Name, productType.ProductTypeId, products.ProductId } into g
select new
{
ProductName = g.Key.Name,
ProductID = g.Key.ProductTypeId,
NumItems = g.Distinct().Count()
}).ToList();
Your composite key (Name, ProductTypeId, ProductId) defines the unique elements by which your data will be grouped by. Looking at the sample data you provided you can quickly see that there are four unique combinations:
(Name, ProductTypeId, ProductId)
(CategoryA, 1, 1)
(CategoryA, 2, 1)
(CategoryB, 3, 2)
(CategoryC, 4, 3)
That's why you have the output you provided:
(Name, ProductId)
CategoryA 1
CategoryA 1
CategoryB 1
CategoryC 1
To get the groups you do want to have, a regular Linq group join would do (names normalized to camel case):
var ProductTypeList = (from productType in ProductTypes
join product in Products
on productType.ProductTypeId equals product.ProductTypeID into prod
select new
{
ProductTypeId = productType.ProductTypeId,
Name = productType.Name,
Products = prod.ToList(),
NumItems = prod.Count()
}).ToList();
foreach (var item in ProductTypeList)
{
Console.WriteLine("{0} : {1}", item.Name, item.NumItems);
}
Output:
CategoryA : 2
CategoryB : 1
CategoryC : 1
Let me know if this is what you were after.

Related

Need to get max date value from another table to order by product list

I have two tables.
First table is product table as below:
Product
Id Name
1 Apple
2 Desktop
3 Laptop
ProductStatus
Id ProductId LatestUpdatedDate
1 2 01-01-2021
2 2 08-07-2021
I am expecting the below result:
2 Desktop
1 Apple
3 laptop
How to make this query into linq?
Sample that i try
var query= _ProductRepository.Table;
var productStatusHistory = (from psh in _productStatusHistoryRepository.Table
group psh by psh.ProductId into g
select g.OrderByDescending(t => t.CreatedOnUtc).FirstOrDefault());
query = (from q in query
join ps in productStatusHistory on q.Id equals ps.ProductId into l_ps
from ps in l_ps.DefaultIfEmpty()
let index = ps == null ? default(DateTime) : ps.CreatedOnUtc
orderby index
select q);
This query working fine. I want to make this as single query

Linq expression resquested

Let's say I have List of object containing these two records :
EmployeeId - Category - Amount
1 - T - 150
1 - D - 300
The result I want in the final is something looking lie this :
EmployeeId - TAmount - DAmount
1 - 150 - 300
How can I achive this using LINQ, I just don't see how to do this with a simple group by on my EmployeeId field ...
var employeeId = 1;
var query =
from row in table
group row by row.EmployeeId into g
where g.Key == employeeId
select new
{
EmployeeId = row.Key,
TAmount = g.SingleOrDefault(r => r.Categpry == "T"),
DAmount = g.SingleOrDefault(r => r.Categpry == "D"),
};

sorting with related tables in mysql

I cant remember the right aproach in php to sort data from related tables anymore? Iam not sure if its even possible in one query?
table brands
id name
------------
1 Disney
2 Pepsi
3 Sony
table products
id name brandId
-----------------------
1 cd-playerX 3
2 nice poster 1
3 usb-radio 3
4 cd-playerY 3
I want to list all the products sorted by the name of the brand table (order=asc) like this:
nice poster (Disney)
cd-playerX (Sony)
cd-playerY (Sony)
usb-radio (Sony)
Anyone?
select p.name + ' (' + b.name + ')' as fullName
from products as p
left join brands as b
on p.id = b.brandId
order by b.name asc, p.name asc --optional for brands with multiple products

query each month record in the table by linq

I have a datatable named testable, it has two columns id(primary key, int) and time(datetime). I want to calculate the number of records of every specific month in the table. For example, there are 5 rows in the table,
Id datetime(d/m/y)
1 12/3/2011
2 15/3/2011
3 4/4/2011
4 1/8/2011
5 19/12/2011
How to write a Linq query to query out the record like this,
Id datetime count
1. 1/2011 0
2. 2/2011 0
3. 3/2011 2
4. 4/2011 1
5. 5/2011 0
6. 6/2011 0
7. 7/2011 0
8. 8/2011 1
9. 9/2011 0
10. 10/2011 0
11. 11/2011 0
12. 12/2011 1
I have written a query statement like this,
var query = from c in testtable.AsEnumerable()
group c by new
{
years = Convert.ToDateTime(c.Field<string>("Posted")).Year,
months = Convert.ToDateTime(c.Field<string>("Posted")).Month
}
into d
orderby d.Key.years,d.Key.months
select new
{
Date = String.Format("{0}/{1}",d.Key.months,d.Key.years),
Count = d.Count()
};
But it only queries out the month 3/4/8/12, it can’t query out other month records.
Anyone can help?
You need to generate a sequence of all dates and left join your existing query with that sequence.
var allMonths = Enumerable.Range(1, 12)
.Select(i => String.Format("{0}/{1}", i, "2011"));
var query = new[]
{
new{ Date= "3/2011" , Count = 2},
new{ Date= "4/2011" , Count = 1},
new{ Date= "8/2011" , Count = 1},
new{ Date= "12/2011", Count = 1},
};
var query2 = from month in allMonths
join date in query on month equals date.Date into g
from date in g.DefaultIfEmpty()
select new
{
Date = month,
Count = (date == null) ? 0 : date.Count
};
foreach (var q in query2)
{
Console.WriteLine(q);
}

LINQ distinct on 2 fields

I have a LINQ query that returns data and I want to filter based on 2 fields (fkProfileID and fkOrgID) that are often the same. I only want to show 1 record when fkProfileID and fkOrgID match, so it is similar to doing an SQL distinct, but on 2 fields rather than one.
My data will look like this (other fields have been removed) :
fkProfileID fkOrgID
1 1001
1 1001
1 1001
2 1001
2 1001
1 1005
1 1005
So here I want to return only the following:
fkProfileID fkOrgID
1 1001
2 1001
1 1005
Here is my current LINQ (both fields above are in tblUserRights), how do I need to change it to do this?
List<ProfileJSON> lstProfiles = (from r in _database.tblUserRights
join p in _database.LuProfiles on r.fkProfileID equals p.luProfileID
join o in _database.tblOrganisations on r.fkOrgID equals o.pkOrgID
where r.fkUniqueID == intPKUserID
orderby o.OrgDesc, p.ProfileName
select new ProfileJSON
{
SiteID = o.pkOrgID,
SiteName = o.OrgDesc,
ProfileID = p.luProfileID,
ProfileName = p.ProfileName
}).ToList();
You can use .Distinct() after your query
List<ProfileJSON> lstProfiles = (from r in _database.tblUserRights
join p in _database.LuProfiles on r.fkProfileID equals p.luProfileID
join o in _database.tblOrganisations on r.fkOrgID equals o.pkOrgID
where r.fkUniqueID == intPKUserID
orderby o.OrgDesc, p.ProfileName
select new ProfileJSON
{
SiteID = o.pkOrgID,
SiteName = o.OrgDesc,
ProfileID = p.luProfileID,
ProfileName = p.ProfileName
}).Distinct().ToList(); //Distinct here

Resources