How do I change this query to an outer join so that customers with no orders still appear in the results?
Customers
.Join(
Orders,
c => c.ID,
r => r.ID,
(c, r) =>
new
{
Name = c.Name,
Address = c.Address,
OrderNumber = r.OrderNumber,
OrderDetails = r.OrderDetails
}
).ToList()
from c in context.Customers
join o in context.order on new { cid = c.cid } equals new { cid = o.cid } into ljoin
from l in ljoin.DefaultIfEmpty()
select new()
{
//whatever
};
Related
I have these two tables: Category (Parent) and Product (Children).
I could use inner join with LINQ query syntax. But with method syntax, I could not get. p. doesn't load CategoryID
var db = new NorthwindEntities();
var cats = db.Categories;
var prods = db.Products;
var catProducts1 = from c in db.Categories
join p in db.Products
on c.CategoryID equals p.CategoryID
select new { c.CategoryName, p.ProductName };
var catProducts2 = db.Categories
.Join(db.Products, c=>c.CategoryID,p=>p);
Below is the correct syntax of Join lamda syntax for your scenario:
var catProducts2 = db.Categories.Join(db.Products,
c => c.CategoryId,
p => p.CategoryID,
(c, p) => new { c.CategoryName, p.ProductName })
.Select(s => new { s.CategoryName, s.ProductName });
You can check the usage of above query at fiddle -- https://dotnetfiddle.net/C3N2I2
I'm trying to write a linq query which should sum order_detail lines from the Northwind.mdb and then return a summarized total along with a few details of the employee responsible. I'm using LINQpad to test it and this is what I have so far
void Main()
{
var result = (from e in Employees
join o in Orders on e.EmployeeID equals o.EmployeeID
join d in OrderDetails on o.OrderID equals d.OrderID
where o.OrderID == 10250
group new { e, o, d } by new
{
o.OrderID, e.Address, e.BirthDate, e.City, e.Country,
e.LastName, e.FirstName, e.Title, e.TitleOfCourtesy, e.HireDate,
e.Region, e.PostalCode, e.HomePhone,
e.Extension, e.ReportsTo,e.PhotoPath, e.EmployeeID,
d.Quantity, d.UnitPrice, d.Discount
}
into grp select new
{
Name = grp.Key.FirstName + " " + grp.Key.LastName,
OrderID = grp.Key.OrderID,
Address = grp.Key.Address,
SalesTotal = grp.Sum(x => x.d.UnitPrice * x.d.Quantity)
});
result.Dump();
}
Output from LINQPad
I was expecting just one line with a total of 1813.00. Can someone tell me what I'm doing wrong?
You're not grouping at the right level. If you change it to group by the employee, then you should get the right results:
void Main()
{
var result = (from e in Employees
join o in Orders on e.EmployeeID equals o.EmployeeID
join d in OrderDetails on o.OrderID equals d.OrderID
where o.OrderID == 10250
group new { e, o, d } by new
{
e.EmployeeID, e.FirstName, e.LastName, e.Address
}
into grp select new
{
Name = grp.Key.FirstName + " " + grp.Key.LastName,
Address = grp.Key.Address,
SalesTotal = grp.Sum(x => x.d.UnitPrice * x.d.Quantity)
});
result.Dump();
}
If you want one line per Order, group by that too:
void Main()
{
var result = (from e in Employees
join o in Orders on e.EmployeeID equals o.EmployeeID
join d in OrderDetails on o.OrderID equals d.OrderID
where o.OrderID == 10250
group new { e, o, d } by new
{
e.EmployeeID, e.FirstName, e.LastName, e.Address,
o.OrderID
}
into grp select new
{
Name = grp.Key.FirstName + " " + grp.Key.LastName,
OrderID = grp.Key.OrderID,
Address = grp.Key.Address,
SalesTotal = grp.Sum(x => x.d.UnitPrice * x.d.Quantity)
});
result.Dump();
}
Here I want to join the out put of the first query(one column) to the result of the 2nd query to get a one result set. How can I merge them.(CONCAT doesn't work as required. eg: var query2 = query.concat(query1);)
var query = (from PP in _db.paymentPlans
join APP in _db.Applications on PP.applicationID equals APP.ApplicationId
join C in _db.Courses on APP.courseID equals C.courseID
where PP.active == true && APP.agentID == agentID
orderby C.courseID ascending
group new {C,PP} by new {C.courseID} into totalRecievable
select new PdPpAppCourseModel
{
courseID = totalRecievable.Key.courseID,
totalAmount = totalRecievable.Sum(x => x.PP.totalAmount)
}).ToList();
var query1=(from PD in _db.paymentDetails
join PP in _db.paymentPlans on PD.paymentPlanID equals PP.paymentPlanID
join APP in _db.Applications on PP.applicationID equals APP.ApplicationId
join C in _db.Courses on APP.courseID equals C.courseID
where PP.active == true && APP.agentID == agentID
orderby C.courseID ascending
group new { C,PD } by new { C.courseID, C.cricosCode, C.courseName } into paymentsCourseWise
select new PdPpAppCourseModel
{
courseID = paymentsCourseWise.Key.courseID,
cricosCode = paymentsCourseWise.Key.cricosCode,
courseName = paymentsCourseWise.Key.courseName,
paidAmount = paymentsCourseWise.Sum(x => x.PD.paidAmount)
}).ToList();
You could join query1 and query like this
var result = (from q1 in query1
join q in query on q1.courseID = q.courseID
select new PdPpAppCourseModel
{
courseID = q1.Key.courseID,
cricosCode = q1.Key.cricosCode,
courseName = q1.Key.courseName,
paidAmount = q1.Sum(x => x.PD.paidAmount),
totalAmount = q.totalAmount
}).ToList();
I try to translate this SQL code :
SELECT w.Id, w.LastName, w.FirstName, SUM(d.Price*dt.Number) AS somme
FROM Waiter w
INNER JOIN Client c on w.Id = c.WaiterId
INNER JOIN DisheOnTable dt on c.Id = dt.ClientId
INNER JOIN Dishe d on dt.DisheId = d.Id
GROUP BY w.Id, w.LastName, w.FirstName
ORDER BY somme DESC;
in entity framework.
I tried something like this
var query2 = (from w in db.Waiter
join c in db.Client on w.Id equals c.WaiterId
join dt in db.DisheOnTable on c.Id equals dt.ClientId
join d in db.Dishe on dt.DisheId equals d.Id
group w by new { w.Id, w.LastName, w.FirstName } into g
//orderby g.Select() descending
select new
{
id = g.Key.Id,
lastname = g.Key.LastName,
firstname = g.Key.FirstName,
total = g.Sum(q => q.)
});
but my sum doesn't work (after multiple research and try) and i don't know how to multiply my variables.
PS : The SQL statement works well, i tried it.
Thank you for helping guys ! :)
You need to group on both dish and DishOnTable alias as Price is in Dish and Number is in DishOnTable:
group new{ d,dt} by new {w.Id, w.LastName, w.FirstName} into g
and now sum the columns which you want from it
select new {
id = g.Key.Id,
lastname = g.Key.LastName,
firstname = g.Key.FirstName,
total = g.Sum(q => q.d.Price * q.dt.Number)
}).OrderBy(x=>x.total)
I have some SQL and am trying to make the equivalent in LINQ. This is the SQL:
SELECT Categories.CategoryDescription, Categories.CategoryType AS Type,
Categories.Category, COUNT(CategoryLinks.OrgID) AS CountOfOrgs
FROM CategoryLinks
INNER JOIN Categories ON Categories.CategoryID = CategoryLinks.CategoryID
GROUP BY Categories.Category, Categories.CategoryType, Categories.CategoryDescription
ORDER BY CategoryDescription ASC
Essentially, I want a list of everything from the Categories table and a count of the number of OrgId's in the CategoryLinks table that links to it.
Below is the query I am performing at the moment. There has to be a more efficient way to do this. Am I wrong?
var cnts = (from c in db.Categories
join cl in db.CategoryLinks on c.CategoryID equals cl.CategoryID
group new { c, cl } by new
{
c.CategoryID
} into g
select new
{
CategoryID = g.Key.CategoryID,
categoryCount = g.Count()
});
var results = (from c in db.Categories
join cn in cnts on c.CategoryID equals cn.CategoryID
select new
{
c.CategoryID,
c.CategoryDescription,
c.CategoryType,
Category = c.Category1,
cn.categoryCount
});
I think you want to use the GroupJoin method:
Categories.GroupJoin(
CategoryLinks,
x => x.CategoryID,
y => y.CategoryID,
(x,y) => new{
x.CategoryID,
x.CategoryDescription,
x.CategoryType,
Category = x.Category1,
CategoryCount = y.Count() })
In query syntax, this is written as join..into:
from c in db.Categories
join cl in db.CategoryLinks on c.CategoryID equals cl.CategoryID into catGroup
select new
{
c.CategoryID,
c.CategoryDescription,
c.CategoryType,
Category = c.Category1,
CategoryCount = catGroup.Count()
}
Try this:
var bbb = categories.Join(categoryLinks, c => c.CategoryID, cl => cl.CategoryId, (c, cl) => new {c, cl})
.GroupBy(g => g.c)
.Select(g => new {count = g.Count(), Category = g.Key});
It returns count and all data that is in Category. We group by all columns in category and place result in new anonymous type variable that contains 2 properties: Count, that contains count and Category that is of type Category and contains all data that is in category row.
If you want, you can rewrite it as:
var bbb = categories.Join(categoryLinks, c => c.CategoryID, cl => cl.CategoryId, (c, cl) => new {c, cl})
.GroupBy(g => g.c)
.Select(g => new
{
CategoryID = g.Key.CategoryId,
CategoryDescription = g.Key.CategoryDescription,
CategoryType = g.Key.CategoryType,
Category = g.Key.Category1,
categoryCount = g.Count()
});