How to left join multiple tables with LINQ - c#

I'm trying to left join three tables with LINQ. I have the SQL working as below:
Select j.Id, u.FirstName , u.LastName, u.Role
From Job j
left join JobTranslator as jt on j.Id = jt.JobId
left join JobRevisor as jr on j.Id = jr.JobId
left join [User] as u on jt.UserId = u.Id OR jr.UserId = u.Id
Where u.Id = someID;
I can get it to work with two joins like below:
IQueryable<Job> jobs =
from j in _db.Jobs
join jr in _db.JobRevisors on j.Id equals jr.JobId into jrs
from jrResult in jrs.DefaultIfEmpty()
join u in _db.Users on jrResult.UserId equals u.Id into jrU
from jrUResult in jrU.DefaultIfEmpty()
where jrUResult.Id == userId
orderby j.Id
select j;
But when I try to join my last needed table it doesn't work like below.
IQueryable<Job> jobs =
from j in _db.Jobs
join jt in _db.JobTranslators on j.Id equals jt.JobId into jts
from jtResult in jts.DefaultIfEmpty()
join jr in _db.JobRevisors on jtResult.Id equals jr.JobId into jrs
from jrResult in jrs.DefaultIfEmpty()
join u in _db.Users on jrResult.UserId equals u.Id into jrU
from jrUResult in jrU.DefaultIfEmpty()
join u in _db.Users on jtResult.UserId equals u.Id into jtU
from jtUResult in jtU.DefaultIfEmpty()
where jtUResult.Id == userId
orderby j.Id
select j;
Any ideas from anyone?

From Linq - left join on multiple (OR) conditions :
IQueryable<Job> jobs = (from j in _db.Jobs
join jt in _db.JobTranslators on j.Id equals jt.JobId into jts
from jtResult in jts.DefaultIfEmpty()
join jr in _db.JobRevisors on jtResult.Id equals jr.JobId into jrs
from jrResult in jrs.DefaultIfEmpty()
join u in _db.Users on jtResult.UserId equals u.Id into jtU
from jtUResult in jtU.DefaultIfEmpty()
where jtUResult.Id == userId
orderby j.Id
select j).Concat(
from j in _db.Jobs
join jt in _db.JobTranslators on j.Id equals jt.JobId into jts
from jtResult in jts.DefaultIfEmpty()
join jr in _db.JobRevisors on jtResult.Id equals jr.JobId into jrs
from jrResult in jrs.DefaultIfEmpty()
join u in _db.Users on jrResult.UserId equals u.Id into jrU
from jrUResult in jrU.DefaultIfEmpty()
where jtUResult.Id == userId
orderby j.Id
select j
).Distinct()

Related

Join Table Group By Summary On Linq

Hi I try to convert the SQL query to LINQ.
SELECT C.ID, SUM(S.AMOUNT*CS.PRICE) AS TOTALCATEGORYSUMMARY
FROM CATEGORY C
INNER JOIN PRODUCT P ON P.CATEGORYID=C.ID
INNER JOIN PSTOCK S ON S.PRODUCTID=P.ID
INNER JOIN PCOST CS ON CS.PRODUCTID=P.ID
GROUP BY C.ID
I try as below:
var qry = from c in categories
join p in products on c.Id equals p.CategoryId
join s in stoks on p.Id equals s.ProductId
join t in costs on p.Id equals t.ProductId
group new {c} by new { c.Name,s.Stock,t.Amount } into ct
select (new { ct.Key.Name, AllCost=ct.Key.Amount * ct.Key.Stock });
How can I do this?
From your SQL query, your LINQ statement should be:
var qry = from c in categories
join p in products on c.Id equals p.CategoryId
join s in stoks on p.Id equals s.ProductId
join t in costs on p.Id equals t.ProductId
group new { c.Id, s.Amount, t.Price } by c.Id into ct
select new { Id = ct.Key.Id, AllCost = ct.Sum(x => x.Amount * x.Price) };
References
Group by single property
Enumerable.Sum method

group join with left join group return null

I have a group join with 2 joins group, one of the group joins can be null, in my query C is the group that I join with a left join this query give me and null exception
from A in contexto.A.Where(i => i.EmpresaId == id)
join B in contexto.B
on A.Id equals B.AId
join D in contexto.D
on B.BId equals D.Id
join C in contexto.C
on A.Id equals C.AId
into c
from C in c.DefaultIfEmpty()
group new { A, C, D} by A into grupo
select new ADTO{
Clave = grupo.Key.Clave,
Nombre = grupo.Key.Nombre,
Lista1 = grupo.Select(t =>
t.D.Nombre
).ToList(),
Valores1 = grupo.Select(t => new ValorDTO
{
a= t.C.A,
b= t.C.B,
c= t.C.c
}
).DefaultIfEmpty(new ValorBMDTO()).ToList()
}).ToList();

return one record from IQueryable query

Hi guys i have this query
public IQueryable<HeaderMRC> ShowHeader(int MRCId)
{
return from m in _ctx.MaterialRequestContractorDetails
where m.MaterialRequestContractorId == MRCId
join materialRequestContractor in _ctx.MaterialRequestContractors on m.MaterialRequestContractorId equals materialRequestContractor.Id
join mat in _ctx.MaterialDescriptions on m.MaterialDescriptionId equals mat.Id
join l in _ctx.Lines on m.LineId equals l.Id
join s in _ctx.Sheets on l.Id equals s.LineId
select new HeaderMRC()
{
Code = materialRequestContractor.Code,
UnitArea = l.Unit,
LineType = l.Type,
RequestDate = materialRequestContractor.RequestDate
};
}
This query produces more than one record but i just need the first one ,how can i return the first value as IQueryable
Just add .First() or .FirstOrDefault()
return (from m in _ctx.MaterialRequestContractorDetails
where m.MaterialRequestContractorId == MRCId
join materialRequestContractor in _ctx.MaterialRequestContractors on m.MaterialRequestContractorId equals materialRequestContractor.Id
join mat in _ctx.MaterialDescriptions on m.MaterialDescriptionId equals mat.Id
join l in _ctx.Lines on m.LineId equals l.Id
join s in _ctx.Sheets on l.Id equals s.LineId
select new HeaderMRC()
{
Code = materialRequestContractor.Code,
UnitArea = l.Unit,
LineType = l.Type,
RequestDate = materialRequestContractor.RequestDate
}).FirstOrDefault();
OR
return (from m in _ctx.MaterialRequestContractorDetails
where m.MaterialRequestContractorId == MRCId
join materialRequestContractor in _ctx.MaterialRequestContractors on m.MaterialRequestContractorId equals materialRequestContractor.Id
join mat in _ctx.MaterialDescriptions on m.MaterialDescriptionId equals mat.Id
join l in _ctx.Lines on m.LineId equals l.Id
join s in _ctx.Sheets on l.Id equals s.LineId
select new HeaderMRC()
{
Code = materialRequestContractor.Code,
UnitArea = l.Unit,
LineType = l.Type,
RequestDate = materialRequestContractor.RequestDate
}).First();
FirstOrDefault will return the first one, or if there isn't one Default(T) which is usually null if it is a class object...
So to get it as a IQueryable which doesn't seem to me like the thing to do:
return new List<HeaderMRC> { (from m in _ctx.MaterialRequestContractorDetails
where m.MaterialRequestContractorId == MRCId
join materialRequestContractor in _ctx.MaterialRequestContractors on m.MaterialRequestContractorId equals materialRequestContractor.Id
join mat in _ctx.MaterialDescriptions on m.MaterialDescriptionId equals mat.Id
join l in _ctx.Lines on m.LineId equals l.Id
join s in _ctx.Sheets on l.Id equals s.LineId
select new HeaderMRC()
{
Code = materialRequestContractor.Code,
UnitArea = l.Unit,
LineType = l.Type,
RequestDate = materialRequestContractor.RequestDate
}).FirstOrDefault() }.AsQueryable();
Just enclose your query with () and append Take(1), which is the set equivalent of the FirstOrDefault:
return (from m in ...
...
...).Take(1);

How to join and select table data in mvc C#?

In my project I have services.
So in side the service I want to join tables and want to select more than one table data.
So I write this cording.
var query1 = from opv in _opvRepository.Table
join o in _orderRepository.Table on opv.OrderId equals o.Id
join g in _graduandRepository.Table on opv.graduand_id equals g.graduand_id
join pv in _productVariantRepository.Table on opv.ProductVariantId equals pv.Id
join p in _productRepository.Table on pv.ProductId equals p.Id
where (opv.ceremony_id == ceremony_id) &&
(!o.Deleted) && (opv.IsHireItem == true) &&
(!p.Deleted) &&
(!pv.Deleted) && (opv.ceremony_id == ceremony_id)
select opv,g;
But there is error and I can't select opv and g. if I write select opv;it is ok. but i want to select both table.
How can i do it??
Try using anonymous types i.e.
query1 = from opv in _opvRepository.Table
join o in _orderRepository.Table on opv.OrderId equals o.Id
join g in _graduandRepository.Table on opv.graduand_id equals g.graduand_id
join pv in _productVariantRepository.Table on opv.ProductVariantId equals pv.Id
join p in _productRepository.Table on pv.ProductId equals p.Id
where (opv.ceremony_id == ceremony_id) &&
(!o.Deleted) && (opv.IsHireItem == true) &&
(!p.Deleted) &&
(!pv.Deleted) && (opv.ceremony_id == ceremony_id)
select new { table1Val = opv,
table2Val = g
};

LINQ OrderBy Count of Records in a Joined Table

I'm having trouble translating the following tSQL to LINQ to SQL in C#. Any help would be much appreciated:
SELECT P.Name
FROM Product P
INNER JOIN OrderItems OI ON P.productID = OI.productID
INNER JOIN Orders O ON OI.orderID = O.orderId
WHERE P.Active = 1 AND O.Status > 2
ORDER BY count(OI.orderID) DESC
It's the ordering by the COUNT of a JOINED table that's throwing me for a loop.
Here's what I have so far (with no orderby):
from p in CRM.tProducts
join oi in CRM.tOrderItems on p.prodID equals oi.prodID
join o in CRM.tOrders on oi.orderID equals o.orderID
where o.status > 1 && p.active == true
select p;
Thanks for any help!
You need to execute a group by if you want the count
SELECT P.Name
FROM Product P
INNER JOIN OrderItems OI ON P.productID = OI.productID
INNER JOIN Orders O ON OI.orderID = O.orderId
WHERE P.Active = 1 AND O.Status > 2
GROUP BY P.Name
ORDER BY count(*) DESC
I'll assume you actually want the count for each group in the projection.
from p in CRM.tProducts
join oi in CRM.tOrderItems on p.prodID equals oi.prodID
join o in CRM.tOrders on oi.orderID equals o.orderID
where o.status > 1 && p.active == true
group p by p.Name into nameGroup
orderby nameGroup.Count()
select new { Name = nameGroup.Key, Count = nameGroup.Count() };
See comment to question.
How to do "order by" in linq ->
If you have
var alist = .... select new { prd = p, ord = o };
you can do
alist.sort( (a, b) => a.ord.CompareTo(b.ord) );
to sort it in place.

Categories

Resources