C# - Which is syntax in LINQ to EF for this query? - entity-framework

I have two table
Teachers(**int IDT**, int mat, String name ) and Courses(String name, **int IDT**). IDT is FKey in Courses and PKey in Teachers.
Then the teacher cant are in more that 3 courses. My query work fine in sql. My question is, 'How write this in LINQ to EF'?
select p.name, p.mat, p.IDT, count(c.IDT) from Teachers p
left join courses c on c.IDT = p.IDT
group by p.name, p.mat, p.IDT
having count(c.IDT) <3

You can try as shown below.
from p in context.Teachers
join c in context.courses on c.IDT equals p.IDT into j1
from j2 in j1.DefaultIfEmpty()
group j2 by new { p.name, p.mat, p.IDT } into grouped
let theCount = grouped.Sum(e => e != null ? 1 : 0)
where theCount < 3
select new { Name = grouped.Key.name, Mat= grouped.Key.mat,
Idt=grouped.Key.IDT,Count = theCount }

Related

How do you use group by and having clause in EF with parent/child relationship?

How can I write a linq to entities query that includes a group by and a having clause?
For example in SQL:
SELECT * FROM dbo.tblParent p
INNER JOIN
(
SELECT a.ID
FROM dbo.tblParent a
join dbo.tblChild c ON a.ID = c.FkParentID
WHERE a.ColValue = 167
GROUP BY A.ID
HAVING COUNT(c.ID) = 1
) t ON p.ID = t.ID
I found my own answer.
// this is far from pretty but it works as far as I can tell
Apps = (from x in context.tblParents
join t in (
from p in context.tblParents
join c in context.tblChilds
on p.ID equals c.FkParentID
where p.ColValue == 167
group c.ID by p.ID into grouped
where grouped.Count() == 1
select new { grouped.Key }) on x.ID equals t.Key
select x);

linq subquery join and group by

Hi is it possible to translate the below queries into linq ? ...
I am using entity frameworks core and tried to use the stored procedure but it seems like i have to create a model that applies to the metadata of the stored procedure. So i am trying to understand whether this kinda such query can be translated into linq so i don't have to create a separate db model.
SELECT
Stock.stockID ProductID,
stockName ProductName,
categoryName ProductCategory,
typeName ProductType,
sizeName ProductSize,
currentQuantity CurrentQuantity,
standardQuantity QuantityPerBox,
CONVERT(VARCHAR(255),CONVERT(INT,Stock.price)) AvgUnitCost,
CONVERT(VARCHAR(255),CONVERT(INT,x.lastUnitCost)) LastOrderUnitCost,
CONVERT(VARCHAR(10),CONVERT(DATE,x.lastOrderDate)) LastOrderDate
FROM dbo.Stock
LEFT JOIN
(
SELECT stockID,unitPrice lastUnitCost ,orderDate lastOrderDate, ROW_NUMBER() OVER (PARTITION BY stockID ORDER BY orderDate DESC) rn FROM dbo.SalesOrder
JOIN dbo.SalesOrderDetail ON SalesOrderDetail.salesOrderID = SalesOrder.salesOrderID
WHERE customerID = #customerID AND salesStatus = 'S'
) x ON x.stockID = Stock.stockID AND rn = 1
LEFT JOIN dbo.StockCategory ON StockCategory.stockCategoryID = Stock.stockCategoryID
LEFT JOIN dbo.StockType ON StockType.stockTypeID = Stock.stockTypeID
LEFT JOIN dbo.StockSize ON StockSize.stockSizeID = Stock.stockSizeID
WHERE disStock = 0
Almost everything is possible. you just need to be careful with performance.
var query =
from stock in db.Stocks
join x in (
from grp in (
from so in db.SalesOrders
join sod in db.SalesOrderDetails on so.SalesOrderId equals sod.SalesOrderId
where so.CustomerId == customerId && so.SalesStatus == "S"
orderby so.OrderDate descending
select new {
sod.StockId,
LastUnitCost = sod.UnitPrice,
LastOrderDate = so.OrderDate
} into inner
group inner by inner.StockId)
select grp.Take(1)) on x.StockId equals stock.StockId into lastStockSales
from x in lastStockSales.DefaultIfEmpty()
join sc in db.StockCategories on stock.StockCatergotyId equals sc.StockCategoryId into scLeft
from sc in scLeft.DefaultIfEmpty()
join st in db.StockTypes on stock.StockTypeId equals st.StockTypeId into stLeft
from st in stLeft.DefaultIfEmpty()
join ss in db.StockSizes on stock.StockSizeId equals ss.StockSizeId into ssLeft
from ss in ssLeft.DefaultIfEmpty()
where stock.DisStock == 0
select new MyDTO {
ProductId = stock.StockId,
ProductName = stock.StockName,
ProductType = st.TypeName,
ProductSize = ss.SizeName,
CurrentQuantity = stock.CurrentQuantity,
QuantityPerBox = stock.StandardQuantity,
AvgUnitCost = stock.Price,
LastOrderUnitCost = x.LastUnitCost,
LastOrderDate = x.LastOrderDate
};
As you can see is easy to rewrite these queries, I had to change a little bit the logic on how to get the latest sales for a stock item since ROW_NUMBER() OVER (PARTITION... is not supported from a LINQ perspective. Again, you would have to consider performance when rewriting queries.
Hope this helps.

GROUP and SUM in Entity Framework

I want to select sum of all (paid) prices of an order item for each customer.
Here is SQL command:
SELECT c.name,SUM(oi.price * oi.count) from customer c
JOIN order o ON c.id=o.customer_id
JOIN order_item oi ON o.id=oi.order_id
JOIN bill b ON b.id=oi.bill_id
WHERE b.payment_id is NOT null
GROUP by c.name;
I don't know how to do this in EF.
Example result:
John Smith 1500,2
Allan Babel 202,0
Tina Crown 3500,78
(comma is used as decimal point..because price is decimal value)
Your example result doesn't seem to match your SQL command, but i think you are looking for something like this:
var query = from c in context.Customers
join o in context.Orders on c.id equals o.customer_id
join oi in context.OrderItems on o.id equals oi.order_id
join b in context.bill on oi.bill_id equals b.id
where b.payment_id != null
group oi by c.name into g
select new
{
Name = g.Key,
Sum = g.Sum(oi => oi.price * oi.count),
}

Entity Framework Linq Query of 3 tables

I have this 3 table query that doesn't return any results. Does anybody have any suggestions on what I am doing wrong? _id is a global variable.
'If there is a guest list then display each person in it
Dim guests = (From g In myEntities.GuestLists
From p In myEntities.Pictures
From u In myEntities.UserProfiles
Where g.EventID = _id
Where p.UserID = g.GuestID
Where u.UserID = g.GuestID
Select New With {p.ImUrl, u.FirstName, u.LastName, u.UserID}).SingleOrDefault()
Repeater1.DataSource = guests
Repeater1.DataBind()
This syntax works for a single table or two table query so I assumed 3 tables would be the same.
I think you have to JOIN the tables.
Like this (untested!)
From g In myEntities.GuestLists
Join p In myEntities.Pictures On g.GuestID Equals p.UserID
Join u In myEntities.UserProfiles On g.GuestID Equals u.UserID
Where g.EventID == _id
Select New With {p.ImUrl, u.FirstName, u.LastName, u.UserID}

Entity Framework 4 INNER JOIN help

Can anyone tell me how to write the following query in Entity Framework 4.0? "Blogs" and "Categories" are my entities. The query basically returns me the list of categories and the number of blogs that are in that category.
SELECT b.CategoryId, c.Value, Count(b.Id) AS [Count] FROM dbo.Blogs b
INNER JOIN dbo.Categories c ON b.CategoryId = c.Id
GROUP BY b.CategoryId, c.Value
Thanks in advance.
The following should work (LinqToEntities):
var categories = from c in oc.Categories
select new
{
CategoryId = c.Id,
c.Value,
Count = c.Blogs.Count()
}
This will give you a list of category ids and values and for each category id you get the number of blogs in that category.
EDIT: To give an answer to the question in your comment: this isn't possible in LinqToEntities but you can do it in Entity SQL.
var results = new ObjectQuery<DbDataRecord>(
#"SELECT y, COUNT(y)
FROM MyEntities.Blogs AS b
GROUP BY YEAR(b.CreatedDate) AS y", entities).ToList();
var nrBlogsPerYear = from r in results
select new { Year = r[0], NrBlogs = r[1] };
In the Entity SQL query, you should replace MyEntities with the name of your context.
EDIT: As I just found out through a comment by Craig, grouping by year is possible in L2E so you can write your query like this:
var nrBlogsPerYear = from b in oc.Blogs
group b by b.CreatedDate.Year into g
select new { Year = g.Key, NrBlogs = g.Count() };
If you have navigation properties in your entities, you can do that :
var cats = from c in db.Categories
let count = c.Blogs.Count()
where count > 0
select new
{
CategoryId = c.Id,
Value = c.Value,
Count = count
};
If you prefer to use an explicit join, you can do it like that :
var cats = from c in db.Categories
join b in db.Blogs on c.Id equals b.CategoryId into g
select new
{
CategoryId = c.Id,
Value = c.Value,
Count = g.Count()
};
var query = from p in B.Products
join c in B.Categories on p.CategoryID equals c.CategoryID
orderby c.CategoryName,p.ProductName
select new
{
c.CategoryName ,
p.ProductName,
p.ReorderLevel
};
GridView1.DataSource = query.ToList();
GridView1.DataBind();