LINQ concatenate values from associated tables - c#

Let'say there's a basic SQL db with the following structure:
Customers table
Customer ID
Name
PostCode
Email
Orders table
Order ID
Customer ID
Description
Items table
Item ID
Order ID
Name
Cost
So a customer can have many orders and an order can have many items.
What's the most appropriate LINQ query to run in order to achieve the following result where the Order Item Names result is a comma separated string:
Customer Name | Customer Email | Order Item Names
So effectively the Orders table is acting like a link table between the Customer and Order Items tables. I then want to concatenate the names of all items which are associated with all orders into a single string and return it in the same result as the customer details.
I've got the following working as expected which will return a result for each order item:
IQueryable<CustomerSearchResult> customerSearchResult = from customer in db.Customers
join order in db.Orders on customers.CustomerId equals order.CustomerId
join item in db.OrderItems on order.OrderId equals item.OrderId
where customerId.Equals(userId)
select new CustomerSearchResult {
customerName = customer.Name,
customerEmail = customer.Email,
itemName = item.Name
};
EDIT 21st March 2014
There are some cases when there will be no associated OrderItems in which case the CustomerSearchResult should still be returned but with the ItemNames property empty.

After you have results
var query = from c in db.Customers
join o in db.Orders on c.CustomerId equals o.CustomerId
join i in db.OrderItems on o.OrderId equals i.OrderId
where c.CustomerId == userId
select new {
CustomerName = c.Name,
CustomerEmail = c.Email,
ItemName = i.Name
};
Group them and concatenate item names:
var result = from r in query.AsEnumerable()
group r by new { r.CustomerName, r.CustomerEmail } into g
select new CustomerSearchResult {
CustomerName = g.Key.CustomerName,
CustomerEmail = g.Key.CustomerEmail,
ItemNames = String.Join(",", g.Select(r => r.ItemName))
};
You should do names concatenation in-memory, because EF will not be able to translate it into SQL.

Related

LINQ Unable to get distinct value from many to many Entity Framework

I am using linq to query many to many relationship
I have those tables/entities :
Each order has multiple products and I want to get distinct order with products.
Here is my query:
var query = (from order in db.Order
join orderproduct in db.OrderProduct
on order.orderId equals orderproduct.OrderId
join product in db.Product
on orderproduct.ProductId equals product.productId
select new
{ order.orderId,
order.name,
product.productId,
product.productName,
product.price
}).Distinct().ToList();
This is the result :
I want to get only name "Jane" with 2 products. The result is showed 2 records with same name "Jane".
How to get one record name "jane" and 2 products?
Thanks for your help.
use the following:
var query = (from order in db.Order
join orderproduct in db.OrderProduct
on order.orderId equals orderproduct.OrderId
join product in db.Product
on orderproduct.ProductId equals product.productId
select new {order.orderId,order.name,product.productId,product.productName,product.price}).GroupBy(order=>order.orderId).ToList();
If you want to return a structure containing the customer's name and its ordered products, I recommend to group the products by order.orderName (not order.orderId) and to load the result into a dictionary:
var query = from order in db.Order
join orderproduct in db.OrderProduct on order.orderId equals orderproduct.OrderId
join product in db.Product on orderproduct.ProductId equals product.productId
group product by order.orderName into orderGroup
select orderGroup;
var orderedProductsByName = query.ToDictionary(name => name.Key, products => products.ToList());

This is my SQL query that is used to retrieve the sum of quantity where product has same id, I want to use it in LINQ

This is my SQL query that is used to retrieve the sum of quantity where
product has same id, I want to use it in LINQ.
select p.ProductId,s.TotalQuantity,p.Title from Products p
join (SELECT ProductId, SUM(Quantity) AS TotalQuantity
FROM SalePerProduct s join Invoices i on s.InvoiceId = i.InvoiceId
where i.IssueDate like '%2016%'
GROUP BY s.ProductId) s
on s.ProductId = p.ProductId;
I have Tried this LINQ query but it does not work fine, It sums up the quantity having same product id but i am unable to show product title using this, need some help.
Thank you in advance.
var sales = from sale in db.SalePerProducts
join product in db.Products
on sale.ProductId equals product.ProductId
where sale.ProductId == product.ProductId
group sale by sale.ProductId into g
select new
{
ProductId = g.Key,
Sum = g.Sum(sale => sale.Quantity),
};
Here is the answer, finally i am able to retrieve multiple products with same name and PRODUCT_ID as a single record ans also sums up the quantity, Thankyou all of you.
Please vote up if you find this useful
var sales = from sale in db.SalePerProducts
join product in db.Products
on sale.ProductId equals product.ProductId
join invoice in db.Invoices
on sale.InvoiceId equals invoice.InvoiceId
where sale.ProductId == product.ProductId &&
invoice.IssueDate.Date == date
group sale by new { sale.ProductId,product.Title } into g
select new
{
ProductId = g.Key.ProductId,
Product_Title = g.Key.Title,
Quantity_Sold = g.Sum(sale => sale.Quantity)
};
var sales = from sale in db.SalePerProducts
join product in db.Products
on sale.ProductId equals product.ProductId
group new {sale, product} by sale.ProductId into g
select new
{
ProductId = g.Key,
Title = g.FirstOrDefault().product.Title,
Sum = g.Sum(s => s.sale.Quantity),
};
I removed unnecessary where clause, you have in your version.

Multiple join with groupby in linq

i have 5 table from which i want to get some information using linq.i am using following query for reading data from data .
var query = (from GRD in _tblStudents.GetQueryable()
join apt in _tblApplicants.GetQueryable()
on GRD.ApplicantID equals apt.ApplicantID
join cls in _tblClasses.GetQueryable()
on GRD.CityID equals cls.ClassID
join prg in _tblPrograms.GetQueryable()
on cls.ProgramID equals prg.ProgramID
join city in _tblCities.GetQueryable()
on GRD.CityID equals city.CityID
where GRD.AcademicYearID == yearId && cls.ProgramID == programId
group apt by new{apt.Gender} into grouped
select new CityWiseStudentModel
{
CityName=city.CityName,
//'city' does not exist in the current context
Gender = grouped.Count(),
programName=prg.Program,
//'prg' does not exist in the current context
}
);
How i can get City name from city table and program name from prg table
group <--> by <--> into <--> is changed your scope to IGrouping<a,b>
My opinion is not only apt.Gender is your key but city.CityName and prg.Program
try this (or some similar):
group apt by new{apt.Gender, city, prg} into grouped
select new CityWiseStudentModel
{
CityName = grouped.Key.city.CityName,
Gender = grouped.Count(), //rename GenderCount
programName = grouped.Key.prg.Program,
// Gender = grouped.Key.Gender,
}
Remember that grouped will only hold the things you've grouped. If you only group adt, then city and prg will not be available in your select.
So you'll need to:
Include city and program into grouped (otherwise they're not available)
Access CityName and Program inside the grouped collection
Something like this should do the trick:
...
group new { apt, cls, prg, city } by new{apt.Gender} into grouped
select new CityWiseStudentModel
{
CityNames = grouped.Select(g => g.city.CityName),
...
programNames = grouped.Select(g => g.prg.Program)
}

How to select CompanyName and number of its products?

I want to write a Linq query that will return, columns with CompanyName of Supplier and number of all products of this company. Can you help me?
So far I got this:
var company = from pro in db.Products
join sup in db.Suppliers
on pro.SupplierID equals sup.SupplierID
group pro by pro.SupplierID
into g
select new { Name = g.Key, COUNT = g.Count() };
But this returns SupplierID not CompanyName. Database is Northwnd.
Use group join (i.e. join...into) to join suppliers with products and get all products of supplier in group:
from s in db.Suppliers
join p in db.Products
on s.SupplierID equals p.SupplierID into g
select new {
s.CompanyName,
ProductsCount = g.Count()
}
The following compiles and runs with Linq-for-objects. I can't vouch for whether Linq-to-SQL will cope.
var company = from sup in db.Suppliers
select new
{
Name = sup.CompanyName,
COUNT = db.Products
.Where(pro => pro.SupplierID == sup.SupplierID)
.Count()
};

SQL Query selecting where there are more than 3 distinct

I am having problems with a SQL query, i need a list of consumers having purchased at least 3 different products whose suppliers are from a certain city (Lets say new york).
Tabels Columns:
Tb_Consumer..........Con_ID(PK), Name, City
Tb_Supplier.............Supp_ID(PK), Name, City
Tb_Transactions.....Tran_ID(PK), Supp_ID(FK), Con_ID(FK), PROD_ID(FK)
Tb_Products............Prod(ID(PK), Name
What i have so far:
var query8Result = (from c in context.Tb_Consumer
join t in context.Tb_Transactions on c.Con_ID equals t.Con_ID
join s in context.Tb_Supplier on t.Supp_ID equals s.Supp_ID
join p in context.Tb_Product on t.Prod_ID equals p.Prod_ID
where s.City == "New York"
select new { Name = c.Name }).Distinct();
I think you need a few Group-by's
var query8Result = (from c in context.Tb_Consumer
join t in context.Tb_Transactions on c.Con_ID equals t.Con_ID
join s in context.Tb_Supplier on t.Supp_ID equals s.Supp_ID
join p in context.Tb_Product on t.Prod_ID equals p.Prod_ID
where s.City == "New York"
group c by new { c.Name, t.Prod_ID } into customerProducts
group customerProducts by new { customerProducts.Key.Name } into customers
where customers.Count() > 3
select g.Key);
Sorry if this isn't 100% correct - It's a little hard to test this...

Categories