multiple tables join by Linq - linq

I have 3 tables which named Player, PlayerDetails and Team. I want to write a linq statement such as
from p in Player join d in PlayerDetails on p.ID equals d.PID
and then right join team table, Player has a column named TID which face to Team table's ID.
I have tried to write a statement like
from p in Player join d in PlayerDetails on p.ID equals d.PID into PlayerGroup
from t in team join g in PlayerGroup on t.ID equals g.p.ID
It certainly can't work. I'm not sure how to write such type of query statement, table left join table2 then right join table3.
Who can help?

I believe you could do something like this:
var LeftJoin =
from p in Player
join d in PlayerDetails on p.ID equals d.PID into pd
from d in pd.DefaultIfEmpty()
select new
{
pID = p.ID,
pTID = p.TID,
dID = d.ID
};
var RightJoin =
from t in Team
join l in LeftJoin on t.ID equals l.pTID into tl
from l in tl.DefaultIfEmpty()
select new
{
tID = t.ID,
pID = l.pID,
pTID = l.PTID,
dID = l.dID
};
To do everything in one query, I think you could do (not tested) something like this:
var RightJoin =
from t in Team
join l in
(from p in Player
join d in PlayerDetails on p.ID equals d.PID into pd
from d in pd.DefaultIfEmpty()
select new
{
pID = p.ID,
pTID = p.TID,
dID = d.ID
})
on t.ID equals l.pTID into tl
from l in tl.DefaultIfEmpty()
select new
{
tID = t.ID,
pID = l.pID,
pTID = l.PTID,
dID = l.dID
};

Related

convert sql to linq with left outer join

I have a sql having left outer join, I want to convert it to linq. the sql is
Select P.Surname, P.Othername H.history
from customers P left outer join historyfiles H on H.patID = P.patId
and H.category1 = 4
where P.id = 2299
Thank you very much.
You can try this:
var query = from p in db.customers.Where(t => t.id == 2299 )
join h in db.historyfiles.Where(l => l.category1 == 4 ) on p.patID equals h.patID into gj
from h in gj.DefaultIfEmpty()
select new { p.Surname, p.Othername, h.History };

Multiple column join in linq

I want to convert this sql query to linq
SELECT Students.StdId, Mark.Value
FROM Departments INNER JOIN
Mark ON Departments.DepId = Mark.DepId INNER JOIN
Students ON Departments.DepId = Students.DepId AND Mark.StdId = Students.StdId
I did this, but it's wont working
from s in Students
join d in Departments on s.DepId equals d.DepId
join m in Marks on new {s.StdId, d.DepId} equals new {m.StdId, m.DepId}
select new{
SId=s.StdId,
Value=m.Value
}
Lets try with
from s in Students
join d in Departments on s.DepId equals d.DepId
join m in Marks
on new {StdId = s.StdId, DepId = d.DepId} equals new {StdId = m.StdId, DepId= m.DepId}
select new{
SId=s.StdId,
Value=m.Value
}
How about
from s in Students
join m in Marks on s.StdId equals m.StdId
join d in Departments on m.DepId equals d.DepId
select new { s.StdId, m.Value };

Linq left outer join and group by issue

Hi All my following query returns results like this:
lstView.DataSource = (from h in context.HolidayMains
join hd in context.HolidayDetails on h.Id equals hd.HolidayMainId into hd2
from hd in hd2.DefaultIfEmpty()
join e in context.Employees on h.CreatedBy equals e.Id into e2
from e in e2.DefaultIfEmpty()
join o in context.OfficeLocations on hd.OfficeLocation equals o.Id into o2
from o in o2.DefaultIfEmpty()
select new
{
h.HolidayTitle,
h.Date,
OfficeLocation = o.Name,
CreatedBy = e.Name,
h.Id
}).ToList();
But I need result like this :
How it can be done?

join on subquery results

I've got a table called IssueStatuses and another table called Issues. Issues has a StatusID and SubStatusID, both of which are from the IssueStatuses table which has an additional field that states if it's a SubStatus or not, like so:
IssueStatuses
IssueStatusID
IssueStatus
IsSubStatus
I'm trying to get a list of SubStatuses for a particular list of Issues. In SQL it's:
SELECT iss.IssueStatus, COUNT(iss.IssueStatus) AS Total
FROM Issues AS Issues
INNER JOIN Rooms r ON Issues.RoomID = r.RoomID
INNER JOIN Locations l ON l.LocationID = r.LocationID
INNER JOIN Customers c ON l.CustomerID = c.CustomerID
INNER JOIN (SELECT * FROM IssueStatuses WHERE IsSubStatus = 0) ist ON Issues.IssueStatusID = ist.IssueStatusID
INNER JOIN (SELECT * FROM IssueStatuses WHERE IsSubStatus = 1) iss ON Issues.IssueSubStatusID = iss.IssueStatusID
WHERE c.Customer = 'ABC'
AND l.Location = 'MySite'
GROUP BY iss.IssueStatus
but I"m having trouble converting it to LINQ. The desired output would be something like:
IssueStatus | Total
-------------------
Open 15
Delayed 25
On Time 8
Here's what I've tried with LINQ:
var query = from i in Issues
join r in Rooms on i.RoomID equals r.RoomID
join l in Locations on r.RoomID equals l.LocationID
join c in Customers on l.CustomerID equals c.CustomerID
where i.IssueStatusID == (from ist in IssueStatuses
where ist.IsSubStatus == false
select ist)
&& i.IssueSubStatusID == (from iss in IssueStatuses
where iss.IsSubStatus == true
select iss)
&& c.Custome == "ABC"
&& l.Location == "MySite"
group i by i.IssueStatus
but I know it's wrong because LINQPad throws an error stating:
can't convert int to type Models.IssueStatus
What I need to do is use iss.IssueStaus to group on but I can't access it. Can someone tell me what I'm doing wrong?
How about this (untested but I should be close):
var query = from i in Issues
join r in Rooms on i.RoomID equals r.RoomID
join l in Locations on r.LocationID equals l.LocationID
join c in Customers on l.CustomerID equals c.CustomerID
join ist in IssueStatuses on i.IssueStatusID equals ist.IssueStatusID
join iss in IssueStatuses on i.IssueSubStatusID equals iss.IssueStatusID
where !ist.IsSubStatus && iss.IsSubStatus
&& c.Customer == "ABC"
&& l.Location == "MySite"
group i by iss.IssueStatus into g
select new {IssueStatus = g.Key, Total = g.Count()}
Your two inner from statements return objects and not IDs ... select the ID you need like ist.IssueStatusID:
var query = from i in Issues
join r in Rooms on i.RoomID equals r.RoomID
join l in Locations on r.RoomID equals l.LocationID
join c in Customers on l.CustomerID equals c.CustomerID
where (from ist in IssueStatuses
where ist.IsSubStatus == false
select ist.IssueStatusID).Contains(i.IssusStatusID)
&& (from iss in IssueStatuses
where iss.IsSubStatus == true
select iss.IssueStatusID).Contains(i.IssueSubStatusID)
&& c.Customer == "ABC"
&& l.Location == "MySite"
group i by i.IssueStatus

GROUP BY and HAVING in linq

I want to convert this code to linq:
select t1.title, COUNT(*)as num
from t1 INNER join t2 on t2.gId = t1.Id
group by t1.title, t1.cId
having t1.cId = 2
I tried this below code:
from p in db.t1s join r in db.t2s on p.Id equals r.gId
where p.cId == 2
group p by p.title into g
select new{ name = from o in g select o.title, num = g.Count()}
But this doesn't return COUNT correctly.
please guide me how can I solve the problem
thanks
Without sample data its hard to get it right, but try this snippet
from p in db.t1s
join r in db.t2s on p.Id equals r.gId
where p.cId == 2
group p by new {p.title, p.cId} into grouped
select new{ name = grouped.Key.title, num = grouped.Count()}
Also, note that this sql:
select t1.title, COUNT(*)as num
from t1 INNER join t2 on t2.gId = t1.Id
group by t1.title, t1.cId
having t1.cId = 2
Will always return 1 as result of COUNT(*). The reason is that you have filtering t1.cId = 2 and grouping by t1.cId as second parameter.

Resources