Trouble translating SQL query to LINQ with join and having count - c#

I have this SQL query that I need to translate to LINQ.
SELECT p.productId, p.name, COUNT(np.ID) AS 'salesLast70', p.quantity
FROM Products p
LEFT JOIN NOrderProducts np
ON np.product_id = p.productId
WHERE np.date_picked > DATEADD(DAY, -70, getdate())
GROUP BY p.productId, p.name, p.quantity
HAVING COUNT(np.ID) < p.quantity
Right now I have the following LINQ query.
var date70 = DateTime.Now.AddDays(-70).Date;
var almostOutOfStockProducts = from p in db.Products
join np in db.NOrderProducts on p.productId equals np.product_id
where np.date_picked > date70
group np by np.ID into npGrp
where npGrp.Count() < p.quantity
select p;
But p cannot be resolved at the end of the LINQ query at > p.quantity and select p.
I'm sure I am missing something in my LINQ query but I cannot seem to find exactly how to fix it.
EDIT:
I ended up using db.Database.SqlQuery(); with the raw query.

To achieve what you want you have to lift the quantity, name from the product up into the group by. You are doing this in your sql version with the clause GROUP BY p.productId, p.name, p.quantity but you are not doing this in your linq version.
An example would be to do:
var almostOutOfStockProducts = db.Products.Join(db.NOrderProducts, p => p.productId, np => np.product_id, (p, np) => new { p, np })
.Where(x => x.np.date_picked > date70)
.GroupBy(x => new { Quantity = x.p.quantity, Name = x.p.name, ProductId = x.p.productId})
.Where(x => x.Count() < x.Key.Quantity)
.Select(x => new {ProductId = x.Key.ProductId, Quantity = x.Key.Quantity, Name = x.Key.Name});
In the GroupBy I am bringing through the product id, quantity and name from the product into an anonymous type. This then becomes the key so I can use it in the Where clause and also in the Select at the end.

Related

select top products in orders table

I have two tables:
product(id, reference, name)
order(id, productId, date, quantity)
Every order has one or many products. The order table can have many lines of the same product. I need to select the 5 best seller products for today in the order table. I try this join to select the products of every order on today.
from order in orders where order.date == DateTime.Today
join product in products on product.Id equals order.productId
select new {product.name, product.quantity, product.Id};
Now I have a list of products sold on today, which can have multiple lines of the same products.
So I tried this to add the quantity of the repeated product:
for (int i = 1; i <= productList.ToArray().Count(); i++)
{
foreach (var product in productList)
{
if (productList.Contains(product))
quantite += product.Quantite;
else
quantite = product.Quantite;
I didn't find a solution how to get the top 5 articles!
Try following :
var results = (from order in orders on order.date equals DateTime.Today
join product in products on product.Id equals order.productId
select new {name = product.name, quantity = order.quantity, id = product.Id})
.GroupBy(x => x.id)
.Select(x => new { name = x.First().name, id = x.Key, totalQuantity = x.Sum(y => y.quantity)}
.OrderByDescending(x => x.totalQuantity)
.Take(5)
.ToList();
You may run this simple query as native and receive the result.
select * from
(
select p.id, p.name, sum(o.quantity) qty
from "order" as o
inner join product as p on o.productid = p.id
where o.date = current_date
group by p.id -- and p.name if p.id is not primary key
) as t
order by qty desc
limit 5;

Linq query for top parents by number of childs, including this number

In my model, there are entities Article and Tag in many-to-many relation through table ArticleTag.
I want to select "trending tags" - tags with most articles in last X days, and I want this count too.
Basically, I need help creating EF Linq query equivalent to this SQL query, with ideal result being Dictionary<Tag, int>
SELECT TOP 50
t.Id, t.Name, count(*)
FROM ArticleTag at
JOIN Article a ON a.Id = at.ArticleId
JOIN Tag t ON t.Id = at.TagId
WHERE a.DateCreated > '2019-10-01'
GROUP BY t.Id, t.Name
ORDER BY count(*) DESC
Can this be done without having ArticleTag as DbSet in DbContext (since it is not really an entity, and I dont need it besides this query).
You have to use navigation properties for this query and do not need to know anything about ArticleTag table.
var query =
from a in ctx.Articles
from t in a.Tags
where a.DateCreated > someDate
group t by new { t.Id, t.Name } into g
orderby g.Count() descending
select new
{
g.Key.Id,
g.Key.Name,
Count = g.Count()
};
var result = query
.Take(50)
.ToDictionary(x => new Tag { Id = x.Id, Name = x.Name }, x => x.Count);

Changing a SQL query to a linq query - syntax

I'm having problem coding my linq query.
This is my SQL query:
select
price, (cast(sum(Quantity) as decimal(7,2)))
from
OrderDetails
where
ItemID = 1000
group by
price
order by
price
This is my linq query:
var result = from od in db.OrderDetails
where od.ItemID == 1000
orderby od.Price
group by price
select od.price, (cast(sum(od.Quantity) as decimal(7, 2)));
This linq query seems to be incorrect. What is the right syntax?
This should work:
(You need to move the order part to be after the grouping)
var q = (from o in context.OrderDetails
where o.ItemID == 1000
group o by o.price into grp
select new
{
Price = grp.Key,
Quantity = grp.Sum(x => x.Quantity)
}).OrderBy(a => a.Price);

Replacing SQL join and group query with linq query in Entity Framework

I have an existing SQL query:
select
mn.accountid, sum(u.peak), sum(u.text), sum(u.datagig),
sum(p.minutesallowed), sum(p.messagesallowed), sum(p.dataallowed)
from
usage u
inner join
mtn mn on u.mtnid = mn.Id
inner join
[plan] p on p.id = mn.planid
group by
mn.accountid
Using Entity Framework, I'm working on converting this to linq, and I've gotten this far:
var tots = from u in currentUsage
join mn in mtns on u.mtnId equals mn.Id
join p in plans on mn.PlanId equals p.Id
group u by u.AccountId into g
select new MainUsageResults
{
TotalPeakMinutes = g.Sum(x => x.Peak),
TotalData = g.Sum(x => x.DataGig),
TotalMessaging = g.Sum(x => x.Text),
TotalAllowedMinutes = g.Sum(x => ???) ,
TotalAllowedMessages = g.Sum(x => ???) ,
TotalAllowedData = g.Sum(x => ???)
};
I can't figure out how to sum up the data that is on the joined tables. In SQL one would have the whole set of columns available in a join, but it doesn't seem to be the case here. How do I get the sum of the columns on the joined tables in this example?
Thanks to #3-14159265358979323846264, a real nice example can be found here

Equivalent LINQ to SQL code

Am new to this here is my T-SQL
SELECT category.id, category.name,COUNT(job.id) AS countofjobs
FROM category
LEFT OUTER JOIN job ON category.id = job.categoryid AND job.active=1
WHERE category.featured=1
GROUP BY category.id, category.name
ORDER BY category.name
what will be the equivalent LINQ to SQL code? any help will be appreciated
Sorry I forgot to mention that there is no relationship database side, tables have no association at all defined in db, thats the main issue, this is really just sample sql to see how I can write Link to SQL for T-SQL that requires: Left outer join, Count of outer join table records and sorting
var result = dataContext.Categories
.Where(c => c.Featured)
.OrderBy(c => c.Name)
.Select(c => new { c.Id,
c.Name,
CountOfJobs = c.Jobs.Count(j => j.Active) };
Alternatively:
var result = from c in dataContext.Categories
where c.Featured
orderby c.Name
select new { c.Id, c.Name, CountOfJobs = c.Jobs.Count(j => j.Active) };
Since you don't have relationships:
var result = from c in dataContext.Categories
where c.Featured
orderby c.Name
select new {
c.Id,
c.Name,
CountOfJobs = dataContext.Jobs.Count(j => j.categoryId == c.Id && j.Active)
};

Categories