Entity Framework 4 INNER JOIN help - entity-framework

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();

Related

Convert nested T-SQL select query to linq

I have the following SQL query which I am trying to translate to a LINQ query:
SELECT
CustomerId,
SUM(Bills.BillAmount) AS BillAmountTotal,
SUM(COALESCE(Pay.Paid, 0)) AS [Payments]
FROM
Bills
LEFT OUTER JOIN
(SELECT
BillId,
SUM(PaymentAmount) AS [Paid]
FROM
BillPayments
GROUP BY
BillId) Pay ON Pay.BillId = Bills.Id
GROUP BY
CustomerId
I solved it using the following code :
var pay = from p in db.BillPayments
group p by new { p.BillId } into g
select new
{
payKey = g.Key,
TotalPayments = g.Sum(p => p.PaymentAmount)
};
var query = from c in db.Customers
join b in db.Bills on c.Id equals b.CustomerId
join p in pay on b.Id equals p.payKey.BillId into cs
from xx in cs.DefaultIfEmpty()
group new { c, b, xx } by new { c.Name, c.MobilePhone, c.Id, c.CustomerCode } into g
select new
{
Received = g.Key,
TotalPayment = g.Sum(p => p.xx.TotalPayments == null ? 0 : p.xx.TotalPayments),
TotlalBilling = g.Sum(p => p.b.BillAmount),
GrandTotal = g.Sum(p => p.b.BillAmount) - g.Sum(p => p.xx.TotalPayments == null ? 0 : p.xx.TotalPayments)
};

How to add a where clause to an EF query which has a grouping

I'm trying to find the number of bookings each user has made. This code works great - it does a join onto bookings and groups them and then does a count.
var bookingsByUser = from u in _repo.Users()
join b in _repo.Bookings() on u.UserId equals b.CreatedByUserId
into g
select new { UserId = u.UserId, TotalBookings = g.Count() };
However, I now want to exclude a certain restaurant, so I try to add a where clause:
var bookingsByUser = from u in _repo.Users()
join b in _repo.Bookings() on u.UserId equals b.CreatedByUserId
where b.RestaurantId != 21
into g
select new { UserId = u.UserId, TotalBookings = g.Count() };
However now I get an error "A query body must end with a select clause or a group clause". I can't seem to use "where" on the join table to filter the records before grouping. Is there a better way to do this?
Try this:
var bookingsByUser = from u in _repo.Users()
join b in _repo.Bookings() on u.UserId equals b.CreatedByUserId
where b.RestaurantId != 21
group b by u.UserId into sub
select new {
UserId = sub.Key,
TotalBookings = sub.Count()
};

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.

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

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 }

INNER JOIN in EF 4

i have 2 tables master and details,
in EF 4 i want to write a query to retrieve a data like this t-sql
SELECT Table1.Table1ID, Table1.A, Table2.Table2ID, Table2.B
FROM Table1 INNER JOIN
Table2 ON Table1.Table1ID = Table2.Table1Id
i use this :
using(var context =new context())
{
var p = (from i in context.Table1.Include("Table2") select i);
}
but it returns rows in table1 how can i change it to retrieve rows in table2 and have my join?
thanks
I think you are looking for this:
var query = from a in context.Table1
join b in context.Table2 on a.Table1ID equals b.Table1Id
select new
{
a.Table1ID,
a.A,
b.Table2ID,
b.B,
};