I recently ran into some SQL code that looks like this
SELECT
a.Id,
b.Id,
c.Id,
d.Id,
b.Name,
d.Occupation,
FROM TableA a
JOIN TableB b ON a.Id = b.Id
JOIN TableC c ON b.Id = c.Id AND b.Name = a.Name
JOIN tableD d ON c.Id = d.Id AND c.Occupation = d.Occupation
I've never used ANDs inside JOINs like this in a corresponding LINQ query (for context, I use the Entity Framework and LINQ for all of my queries). I usually put all my ANDs inside there where clause like this:
var query = from a in dbContext.TableA
join b in dbContext.TableB on a.Id equals b.Id
join c in dbContext.TableC on b.Id equals c.Id
join d in dbContext.TableD on c.Id equals d.Id
where b.Name = a.Name
where c.Occupation = d.Occupation
select new
{
AId = a.Id,
BId = b.Id,
CId = c.Id,
DId = d.Id,
BName = b.Name,
DOccupation = d.Occupation,
};
What technique can I use to get my LINQ query to match the SQL statement above?
You can join on multiple properties by constructing anonymous types from your properties like this:
var query = from a in dbContext.TableA
join b in dbContext.TableB on new { a.Id, a.Name } equals new { b.Id, b.Name }
join c in dbContext.TableC on b.Id equals c.Id
join d in dbContext.TableD on new { c.Id, c.Occupation } equals new { d.Id, d.Occupation }
select new
{
AId = a.Id,
BId = b.Id,
CId = c.Id,
DId = d.Id,
BName = b.Name,
DOccupation = d.Occupation,
};
Note that the name, order, and datatype of each property in the anonymous types need to be the same on both sides of the equals in order for this to work. Otherwise they would be two different anonymous types and would not be equatable.
Related
I am having diffculties joining a table in my code. Below you can see my code, I am getting an error on the join 2 table trying to connect my parts table.
if (query.Any()) // Check if REG is in the Database
{
int carID = query.FirstOrDefault().Id;
string carRegg = query.FirstOrDefault().regNo;
string carMake = query.FirstOrDefault().Make;
string carModel = query.FirstOrDefault().Model;
var test = (from a in dbC.Cars
where a.Id == carID
join b in dbC.Services on a.Id equals b.ServiceWrkNo
join c in dbC.PartsUseds on b.ServiceWrkNo equals c.PartsUsedNo
join d in dbC.Parts on c.PartsUsedNo equals d.PartName
select new
{
serviceNum = b.ServiceWrkNo,
PartNo = c.PartsUsedNo,
replacedParts = d.PartName
}).ToList();
the database I created from a model first method is below.
Your join do seems a little bit off -- could you try the join with the following columns
var test = (from a in dbC.Cars
where a.Id == carID
join b in dbC.Services on a.Id equals b.CarId
join c in dbC.PartsUseds on b.ServiceWrkNo equals c.ServiceServiceWrkNo
join d in dbC.Parts on c.PartsPartNo equals d.PartNo
select new
{
serviceNum = b.ServiceWrkNo,
PartNo = c.PartsUsedNo,
replacedParts = d.PartName
}).ToList();
I have a sql query which will give me around 30 record but the same query once I changed to linq query its giving me thousands of record. I cant find the actual root cause of the problem can any one help me ...
sql query
select
DLId = p.Id,
TopicId = st.Id,
TopicName = at.Name,
PrimaryOrg = bo.BusinessUnit,
StatusId = ns.ID,
ModifiedBy = pa.LastName
from STopics st
join ATopics at on st.Id = at.Id
join Students p on st.StudentId = p.Id
join Sorgs sbu on at.BUorgID = sbu.BUOrgID
join BOrgs bo on sbu.BUOrgID = bo.ID
join Status ns on st.SID = ns.ID
join Students pa on st.NominatedBy = pa.Email
where p.IsActive = 1 and sbu.StudentID = 123 and sbu.IsActive = 1
and the linq query is
(from st in Context.STopics
join at in Context.ATopics on st.Id equals at.Id
join p in Context.Students on st.StudentId equals p.Id
join sbu in Context.Sorgs on at.BUorgID equals sbu.BUOrgID
join bo in Context.BOrgs on sbu.BUOrgID equals bo.ID
join ns in Context.Status on st.SID equals ns.ID
join pa in Context.Students on st.NominatedBy equals pa.Email
where p.IsActive==true && sbu.StudentID == 123 && sbu.IsActive == true
select new result()
{
DLId = p.Id,
TopicId = st.Id,
TopicName = at.Name,
PrimaryOrg = bo.BusinessUnit,
StatusId = ns.ID,
ModifiedBy = pa.LastName
})
(from st in Context.STopics
join at in Context.ATopics on st.Id equals at.Id
join p in Context.Students on new { st.StudentId, p.IsActive } equals new { p.Id , true}
join sbu in Context.Sorgs on new { sbu.BUorgID, sbu.IsActive,sbu.StudentID } equals new { at.BUorgID , true, 123}
join bo in Context.BOrgs on sbu.BUOrgID equals bo.ID
join ns in Context.Status on st.SID equals ns.ID
join pa in Context.Students on st.NominatedBy equals pa.Email
select new result()
{
DLId = p.Id,
TopicId = st.Id,
TopicName = at.Name,
PrimaryOrg = bo.BusinessUnit,
StatusId = ns.ID,
ModifiedBy = pa.LastName
})
Can you try this one, if you want to get exact issue, you can get how sql query is generated from the linq statements, linq query uses lots of inner query methodology
var query= your linqquery;
string sqlQuery=query.ToString();
you can review sqlQuery.
i want to translate this SQL query :
SELECT FirstName,LastName, WaiterId, Count(*) AS compte
FROM Waiter
INNER JOIN Client on Waiter.Id = Client.WaiterId
GROUP BY WaiterId,lastname, firstname
ORDER BY compte DESC;
in entity framework.
I tried something like this :
var query = (from w in db.Waiter
join c in db.Client on w.Id equals c.WaiterId
group c by c.WaiterId into g
//orderby
select new
{
WaiterId = g.Key,
count = g.Count()
});
but my select don't work. I can't select FirstName and LastName and i don't even know if my count is good.
You need to include all the properties in the group by.
var query = (from w in db.Waiter
join c in db.Client on w.Id equals c.WaiterId
group c by new { c.FirstName, c.LastName, c.WaiterId} into g
orderby g.Count() descending
select new
{
FirstName = g.Key.FirstName,
LastName = g.Key.LastName,
WaiterId = g.Key.WaiterId,
count = g.Count()
});
I am trying to convert below query in linq
select ta.id, ta.name, min(tb.id) from tableA ta
left join tableB tb on tb.fkid=ta.id
group by ta.id, ta.name
I tried below
var query = (from tableA in tableARepository.AsQueryable()
join tableB in tableBRepository.AsQueryable() on
tableA.Id equals tableB.fkid
group grp by new {tableA.Id, tableA.Name } into groupedCol
select new
{
Id = groupedCol.Key.Id,
Name = groupedCol.Key.Name,
fkId = grouppedCol.Min // cant get column fkid from tableB
}
);
I am not able to get Min of column fkid of tableB
What is missing here or how can i fix this?
You should be able to get the results that you are looking for without using Join or GroupBy:
var restrictTo = new[] {1, 2};
var query = tableARepository.AsQueryable()
// I want to add where clause like tableA.Id in (1,2)
.Where(a => restrictTo.Contains(a.Id))
.Select(a => new {
Id = a.Id
, Name = a.Name
, FkId = tableBRepository.AsQueryable().Min(b => b.fkid=a.id)
});
I think you are looking for GroupJoin
from tableA in tableARepository.AsQueryable()
join tableB in tableBRepository.AsQueryable() on
tableA.Id equals tableB.fkid into tb
select new
{
Id = tableA.Id,
Name = tableA.Name,
fkId = tb.Min(x => x.id)
}
I have the following query in VB, but I do not know how to translate it to C# synatax
Dim q = From c In db.Customers
Group Join o In db.Orders On c.CustomerID Equals o.CustomerID Into orders = Group
Select New With {c.ContactName, .OrderCount = orders.Count()}
Thank you
It's actually pretty easy. You just have to drop the "Group":
var q = from c in db.Customers
join o in db.Orders on c.CustomerID equals o.CustomerID into orders
select new { c.ContactName, OrderCount = orders.Count() };
Or, if you're looking for the lambda syntax:
var q = db.Customers.GroupJoin(db.Orders,
o => o.CustomerID,
c => c.CustomerID,
(c, orders) =>
new
{
c.ContactName,
OrderCount = orders.Count()
});
Dim q = From c In db.Customers
Group Join o In db.Orders On c.CustomerID Equals o.CustomerID Into orders = Group
Select New With {c.ContactName, .OrderCount = orders.Count()}
var q =
from c in db.Customers
join o in db.Orders on c.CustomerID equals o.CustomerID into orders
select new {c.ContactName, .OrderCount = orders.Count()};