Linq query with left join and group - c#

I'm unable to convert this SQL query into a working linq statement
select sum(cena), id_auta, max(servis)
from dt_poruchy left outer join mt_auta on dt_poruchy.id_auta=mt_auta.id
where dt_poruchy.servis>=3 group by id_auta;
I tryed something like this but i cant handle the select statement
var auta = from a in MtAuta.FindAll()
join p in DtPoruchy.FindAll() on a equals p.MtAuta into ap
from ap2 in ap.DefaultIfEmpty()
where ap2.SERVIS >= 3
group ap2 by ap2.ID into grouped
select new {
I'll appreciate any help!

Based on the limited information provided (which tables are certain fields from?), here is what I came up with.
var auta = from a in MtAuta.FindAll()
let p = a.DtPoruchys.Where(s => s.SERVIS >= 3)
select new
{
Id = a.Id,
CenaSum = p.Sum(c => c.Cena),
Servis = p.Max(s => s.SERVIS)
};

I've reached this solution (supposing "cena" belongs to MtAuta.FindAll()):
var auta = from e in
(from a in DtPoruchy.FindAll()
where a.SERVIS >= 3
join p in MtAuta.FindAll() on a.MtAuta equals p.Id into ap
from ap2 in ap.DefaultIfEmpty()
select new
{
Cena = ap.cena,
IdAuta = a.MtAuta,
Servis = a.servis
})
group e by e.IdAuta into g
select new
{
Cena = g.Sum(e => e.cena),
IdAuta = g.Key,
Servis = g.Max(e => e.servis)
};

I am not sure which table cena and servis are coming from but to create grouped sum you do something like.
select new { Sum = grouped.Sum( x => x.cena ) }
and to get max
select new { Max = grouped.Group.Max( x => x.servis ) }
Here is a good reference for you.
MSDN - 101 LINQ Samples

I've modified your solution little bit and i got it working like this:
var auta = from jo in
(
from a in MtAuta.FindAll()
join p in DtPoruchy.FindAll() on a equals p.MtAuta into ap
from ap2 in ap.DefaultIfEmpty()
where ap2.SERVIS >= 3
select new
{
Cena = ap2.CENA,
Idauto = ap2.ID_AUTA,
Servis = ap2.SERVIS
}
)
group jo by jo.Idauto into g
select new
{
Cena = g.Sum(jo => jo.Cena),
IdAuto = g.Key,
Servis = g.Max(jo => jo.Servis)
};
I just curious if this is the best solution?

Related

Why does using Linq Group By Sum give me a cast error?

I try using 2 queries to get the result of a subtraction, then a group by sum.
The logic seems good but I have the following error:
unable to implicitly convert type 'System.Collection.Generic.List' <> 'to' int '
My requests:
var postesList = (from od in db.tbl_607_order_details
join o in db.tbl_607_order on od.FK_ID_order equals o.ID
where o.order_number == contract
select new OrderWizardViewModel
{
idPoste = od.ID,
posteNumber = od.poste_number,
contractQ = od.order_quantity,
recievedQ = od.recieved_quantity,
lifeTime = od.gaz_lifetime,
stockMini = od.stock_mini,
shippingDelay = od.shipping_delays,
onTheRoadQ = 0
}).OrderBy(t => t.posteNumber).ToList();
foreach (var item in postesList)
{
item.onTheRoadQ = (from od in db.tbl_607_order_details
join srd in db.tbl_607_shipping_request_details on od.ID equals srd.FK_ID_order_details
where item.idPoste == srd.FK_ID_order_details & srd.shipping_quantity > srd.reception_quantity
select new
{
quantity = (srd.shipping_quantity - srd.reception_quantity.Value)
}).GroupBy(t => t.quantity).Select(x => new { Sum = x.Sum(y => y.quantity) }).ToList();
}
I want fill postesList.onTheRoadQ with the sum of shipping_quantity - reception_quantity
Some idea?
All your statement returns a List, Just Sum in the end to summ all the values of the list.
item.onTheRoadQ = (from od in db.tbl_607_order_details
join srd in db.tbl_607_shipping_request_details on od.ID equals srd.FK_ID_order_details
where item.idPoste == srd.FK_ID_order_details & srd.shipping_quantity > srd.reception_quantity
select srd.shipping_quantity - srd.reception_quantity.Value
).Sum()

Grouping and Sum some field with Sub query in LINQ

I'm trying to convert my sql query to linq, i confused about sum and grouping,
this is my query
SELECT
produk.supplier,
SUM(transaksi.jumlah_transaksi),
SUM(transaksi.nominal_transaksi),
operasional.nominal
FROM
transaksi INNER JOIN produk ON transaksi.id_produk = produk.id_produk
LEFT JOIN
(SELECT
operasional.id_supplier,
SUM(nominal) AS nominal
FROM
operasional) operasional
ON operasional.id_supplier = produk.id_supplier
GROUP BY produk.supplier
output should be
like this
Progress
i am just trying with linq query like this without grouping
var result = from t in db.transaksi
join p in db.produk on t.id_produk equals p.id_produk
from op in
(
from o in db.operasional
select new
{
id_supplier = o.id_supplier,
nominal = o.nominal
}
).Where(o => o.id_supplier == p.id_supplier).DefaultIfEmpty()
select new
{
nama_supplier = p.supplier,
jumlah_transaksi = t.jumlah_transaksi,
nominal_transaksi = t.nominal_transaksi,
biaya_operasional = op.nominal
};
and result query from my linq still like this
SELECT
`p`.`supplier`,
`t`.`jumlah_transaksi`,
`t`.`nominal_transaksi`,
`t1`.`nominal`
FROM
`transaksi` `t`
INNER JOIN `produk` `p`
ON `t`.`id_produk` = `p`.`id_produk`
LEFT JOIN `operasional` `t1`
ON `t1`.`id_supplier` = `p`.`id_supplier`
Solved
and this is my full linq
var result = from t in db.transaksi
join p in db.produk on t.id_produk equals p.id_produk
from op in
(
from o in db.operasional
group o by o.id_supplier into g
select new
{
id_supplier = g.First().id_supplier,
nominal = g.Sum(o => o.nominal)
}
).Where(o => o.id_supplier == p.id_supplier).DefaultIfEmpty()
select new
{
nama_supplier = p.supplier,
jumlah_transaksi = t.jumlah_transaksi,
nominal_transaksi = t.nominal_transaksi,
biaya_operasional = op.nominal
};
var grouped = result
.GroupBy(x => x.nama_supplier)
.Select(x => new
{
nama_supplier = x.Key,
jumlah_transaksi = x.Sum(s => s.jumlah_transaksi),
nominal_transaksi = x.Sum(s => s.nominal_transaksi),
biaya_operasional = x.Select(s => s.biaya_operasional).First()
});
Try to use GroupBy (in following code result is your query from code above):
var grouped = result
.GroupBy(x => x.nama_supplier)
.Select(x => new {
nama_supplier = x.Key,
sum1 = x.Sum(s => s.jumlah_transaksi),
sum1 = x.Sum(s => s.nominal_transaksi),
nominal = x.Select(s => s.biaya_operasional).First()
})
Code is not checked so use it just as idea.

cannot convert mysql query to linq statement

My SQL query that works as expected:
SELECT SUM(outcome), toaddress
FROM lot l
JOIN incomingpayment ip
ON l.incomingpayment_id = ip.id
WHERE outcome > 0
GROUP BY ip.toaddress
ORDER BY SUM(outcome) DESC
I am trying to turn this into a LINQ statement, without great success anyway:
var result =
from l in session.Query<Lot>().ToList()
join ip in session.Query<IncomingPayment>().ToList()
on l.IncomingPayment equals ip
where l.Outcome > 0
group ip by new {ip.ToAddress}
into g
select new
{
Address = g.Key,
SumAmount = g.Sum(x => x.Outcome)
};
Outcome in the last line is a Lot's field and since I'm grouping IncomingPayment (group ip...) it's not available at the g.Sum() call.
What am I missing here?
You could try this:
var result = from g in (from l in session.Query<Lot>().ToList()
join ip in session.Query<IncomingPayment>().ToList()
on l.IncomingPayment equals ip.Id
where l.Outcome > 0
select new { Address = ip.ToToAddress, Outcome = l.Outcome})
group g by g.Address
select new
{
Address = g.Key,
SumAmount = g.Sum(x => x.Outcome)
};
Or more consisely:
Lots = session.Query<Lot>().ToList();
IncomingPayments = session.Query<IncomingPayment>().ToList();
var result = Lots.Join(IncomingPayments,
x=>x.IncomingPayment,
y=>y.Id,
(x,y) => new
{
Address = x.ToToAddress,
OutCome = y.Outcome
}).GroupBy(x => x.Address,
x => x.Outcome,
(kew, group) =>
{
Address = key,
SumAmount = group.Sum()
});

Not counting null values from a linq LEFT OUTER JOIN query

I have this sql query that does exactly what i want but i need it in linq. It returns a few AVC rows and counts how many PersonAVCPermission that has status 1 linked to it
SELECT a.Id, a.Name, a.Address, COUNT(p.AVCID) AS Count
FROM AVC AS a
LEFT OUTER JOIN
(
SELECT PersonAVCPermission.AVCId
FROM PersonAVCPermission
WHERE PersonAVCPermission.Status = 1
) AS p
ON a.Id = p.AVCId
GROUP BY a.Id, a.Name, a.Address
I have this query in linq and it does the same thing except when there are no PersonAVCPermission it still counts 1
var yellows = odc.PersonAVCPermissions.Where(o => o.Status == (int)AVCStatus.Yellow);
var q = from a in odc.AVCs
from p in yellows.Where(o => o.AVCId == a.Id).DefaultIfEmpty()
group a by new { a.Id, a.Name, a.Address } into agroup
select new AVCListItem
{
Id = agroup.Key.Id,
Name = agroup.Key.Name,
Address = agroup.Key.Address,
Count = agroup.Count(o => o.Id != null)
};
Im guessing that with DefaultIfEmpty() it places null rows in the list that then gets counted so i try to exclude them with (o => o.Id != null) but it still counts everything as at least one
If i dont use DefaultIfEmpty() it skips the rows with count 0 completely
How can i exclude them or am i doing it completely wrong?
How about using .Any() and a Let?
var yellows = odc.PersonAVCPermissions.Where(o => o.Status == (int)AVCStatus.Yellow);
var q = from a in odc.AVCs
let Y = (from p in yellows.Where(o => o.AVCId == a.Id) select p).Any()
where Y == true
group a by new { a.Id, a.Name, a.Address } into agroup
select new AVCListItem
{
Id = agroup.Key.Id,
Name = agroup.Key.Name,
Address = agroup.Key.Address,
Count = agroup.Count(o => o.Id != null)
};
You don't need the join, nor the grouping:
var q = from a in odc.AVCs
select new AVCListItem
{
Id = a.Id,
Name = a.Name,
Address = a.Address,
Count = yellows.Where(o => o.AVCId == a.Id).Count()
};

How can I filter results of one LINQ query based on another?

Given the following:
DP_DatabaseTableAdapters.EmployeeTableAdapter employeetableAdapter = new DP_DatabaseTableAdapters.EmployeeTableAdapter();
DP_Database.EmployeeDataTable employeeTable = employeetableAdapter.GetData();
var leadEmployees = from e in employeeTable
where e.IsLead == true
select e;
DP_DatabaseTableAdapters.LaborTicketTableAdapter tableAdapter = new DP_DatabaseTableAdapters.LaborTicketTableAdapter();
DP_Database.LaborTicketDataTable table = tableAdapter.GetDataByDate(date.ToString("MM/dd/yyyy"));
var totHours = from l in table
join e in leadEmployees on l.EmployeeID equals e.EmployeeID
group l by l.EmployeeID into g
orderby g.Key
select new
{
EmployeeID = g.Key,
HoursWorked = g.Sum(s => s.HoursWorked)
};
Total hours correctly filters the results based on the leadEmployee's list of people who have the IsLead bit set to true.
I would like to know how to do this with a where clause, I have attempd to use leadEmployees.Contanis but it wants a whole EmployeeRow...
How can I add what looks to be part of an IN clause to a where filter to replace the join?
var totHours = from l in table
where ??????
group l by l.EmployeeID into g
orderby g.Key
select new
{
EmployeeID = g.Key,
HoursWorked = g.Sum(s => s.HoursWorked)
};
The contains will only want a whole EmployeeRow if you are selecting whole employee roles. You can either:
leadEmployees.Select(e => e.id).contains
OR
leadEmployees.Count(e => e.id == l.id) > 0
Both will work. (Excuse slightly rushed lack of consideration for syntax accuracies).
This should work:
var leadEmployees = from e in employeeTable
where e.IsLead == true
select e.EmployeeID;
var totHours = from l in table
where leadEmployees.Contains(l.EmployeeID)
group l by l.EmployeeID into g
orderby g.Key
select new
{
EmployeeID = g.Key,
HoursWorked = g.Sum(s => s.HoursWorked)
};

Categories

Resources