Convert SQL Server query to Linq query - sql

select c.Name, d.First_Name, COUNT(c.Name) as qty
from order_product_s a
inner join Order_s b on a.Order_Id = b.Id
inner join Product_s c on a.Product_Id = c.Id
inner join Customer_s d on b.Customer_Id = d.Id
where b.Customer_Id = 4869
group by c.Name, d.First_Name

Something like this:
int __UserId = 4869;
var results =
(
from t in
(
from a in Repo.order_product_s
from b in Repo.Order_s
.Where(bb=> bb.id == a.Order_Id)
from c in Repo.Product_s
.Where(cc => cc.Id == a.Product_Id)
from d in Repo.Customer_s
.Where(dd => dd.Id == b.Customer_Id)
where b.Customer_Id == __UserId
select new
{
Name = c.Name
,First_Name = d.First_Name
}
)
group t by new { t.Name , t.First_Name } into g
select new
{
Name = g.Key.Name
,First_Name=g.Key.First_Name
,qty = g.Count( x => x.Name != null)
}
).ToList();
or more compact:
var results =
(
from a in Repo.order_product_s
from b in Repo.Order_s
.Where(bb=> bb.id == a.Order_Id)
// .DefaultIfEmpty() // <== makes join left join
from c in Repo.Product_s
.Where(cc => cc.Id == a.Product_Id)
// .DefaultIfEmpty() // <== makes join left join
from d in Repo.Customer_s
.Where(dd => dd.Id == b.Customer_Id)
// .DefaultIfEmpty() // <== makes join left join
where b.Customer_Id == __UserId
select new
{
Name = c.Name
,First_Name = d.First_Name
}
into t group t by new { t.Name , t.First_Name } into g
select new
{
Name = g.Key.Name
,First_Name=g.Key.First_Name
,qty = g.Count( x => x.Name != null)
// Or like this
// ,qty = g.Select(x => x.Name).Where(x => x != null).Count()
// and if you ever need count(distinct fieldname)
//,qty = g.Select(x => x.GroupName).Where(x => x != null).Distinct().Count()
}
)
// .OrderBy(t => t.Name).ThenBy(t => t.First_Name).ThenBy(t => t.qty) // Order in SQL
.ToList()
// .OrderBy(t => t.Name).ThenBy(t => t.First_Name).ThenBy(t => t.qty) // Order in .NET
;

Related

Converting SQL query to LINQ format - SQL

I have this sql query that needs to be in linq. I'm really new to it so I still cant figure out how to use it.
SELECT a.Fecha, a.ContratoId, a.TotalContrato, a.Plazo, a.ValorCuota, a.Fecha_de_vencimiento
FROM Contrato AS a LEFT JOIN Contrato_detalle AS b ON a.ContratoId = b.ContratoId
AND a.ContratoId < b.ContratoId
Left join Contrato_plan_pagos c on a.ContratoId = c.ContratoId
And a.ContratoId < b.ContratoId
Please try this:
var resultsQueryable = from a in Contrato
join b in Contrato_detalle on a.ContratoId equals b.ContratoId into abGroup
from ab in abGroup where a.ContratoId < ab.ContratoId
join c in Contrato_plan_pagos on a.ContratoId equals c.ContratoId into acGroup
from ac in acGroup where ContratoId < c.ContratoId
select new {
a.Fecha,
a.ContratoId,
a.TotalContrato,
a.Plazo,
a.ValorCuota,
a.Fecha_de_vencimiento
};
var results = resultsQueryable.ToList();
or
var resultsQueryable = Contrato.GroupJoin(Contrato_detalle,
a => a.ContratoId, b => b.ContratoId, (a, comp) => new {v = a, comp})
.SelectMany(x => x.comp, (t1, b) => new { a = t1.v, b = b })
.Where(abGroup => abGroup.a.id < abGroup.b.id)
.GroupJoin(Contrato_plan_pagos, t => t.b.ContratoId, c => c.ContratoId, (t, grp) => new {t, grp})
.SelectMany(t => t.grp, (t, c) => new {a = t.t.a, b = t.t.b, c = c})
.Where(acGroup => acGroup.a.id < acGroup.c.id)
.Select(x => new {
a.Fecha,
a.ContratoId,
a.TotalContrato,
a.Plazo,
a.ValorCuota,
a.Fecha_de_vencimiento
});
var results = resultsQueryable.ToList();
UPDATE:
Since you need to return just Contrato properties, you can further simplify your linq as shown below:
var resultsQueryable = from a in Contrato
join b in Contrato_detalle on a.ContratoId equals b.ContratoId
join c in Contrato_plan_pagos on a.ContratoId equals c.ContratoId
where a.ContratoId < b.ContratoId and a.ContratoId < c.ContratoId
select new {
a.Fecha,
a.ContratoId,
a.TotalContrato,
a.Plazo,
a.ValorCuota,
a.Fecha_de_vencimiento
};
var results = resultsQueryable.ToList();

SQL with max(date) to LINQ

I have tried to make the following sql in linq with no luck can some help mw with this?
select * from customer c
where companynumber = 1
and status <> 0
and lastdate = (select max(lastdate) from customer where customernumber = c.customernumber)
Gives 22 records
My best try was this:
_ctx.Customers
.Where(r => r.CompanyNumber == companyNumber && r.CustomerNumber != null && r.Status != 0)
.GroupBy(c => c.CustomerNumber)
.Select(g => new
{
name = g.Key,
count = g.Count(),
date = g.Max(x => x.LastEdited)
})
.OrderBy(c => c.name);
Gives 22.000+ records
But not the result as the above SQL
UPDATE:
The following LINQ does the trick ;o)
from a in _ctx.Customers
where a.CustomerNumber != null && a.CompanyNumber == companyNumber
group a by new { a.CustomerNumber } into g
select g.OrderByDescending(a => a.LastEdited).FirstOrDefault() into c
where c.Status == 1
select c
I had to move the where c.Status == 1 into my first select statment

How do I convert this SQL outer join to LINQ

I want to convert this to Linq:
SELECT {fields}
FROM tableA AS A
LEFT JOIN tableB AS B
ON B.Field1 = MyVariable
AND ( A.Key = B.Key
OR A.Key = B.AlternateKey)
It's that OR in conjunction with the AND clause that is tripping me over.
EDIT: Can I have the solution as extension methods please.
from a in tableA
from b in tableB.Where(b => b.Field1 == MyVariable && (a.Key == b.Key || a.Key == b.AlternateKey)).DefaultIfEmpty()
select new { a, b };
tableA.SelectMany(
a => tableB.Where(b => b.Field1 == MyVariable && (a.Key == b.Key || a.Key == b.AlternateKey)).DefaultIfEmpty()
.Select(b => new { a, b })
);

How to use the group join result to join another tables using LINQ?

I am not able to use the result of group join and then further applying the join with other tables.
My SQL query is :
SELECT *
FROM
[dummy_database].[dbo].[MA] M
INNER JOIN
SN.dbo.A A ON A.ApplicantMAId = M.MAId
INNER JOIN
SN.dbo.SP SP ON SP.PropertyMAId = M.MAId
INNER JOIN
SN.dbo.MCC CC ON CC.MAId = m.MAId
INNER JOIN
SN.dbo.MLSTN T ON T.MAT_ID = M.MAId
INNER JOIN
(SELECT
MAX(MAT_DATE) AS MaxDate,
MAT_ID
FROM
[SN].[dbo].[MLSTN]
GROUP BY
MAT_ID) Q ON Q.MAT_ID = M.MAId
and what I have done so far is:
var q = (from ml in context.MLSTN
group ml by ml.MAT_ID into g
let maxdate = g.Max(date => date.MAT_DATE)
select new
{
MortgId = g.Key,
TrackingDate = g.FirstOrDefault(val => val.MAT_DATE == maxdate).MAT_DATE
}
);
but now this result is not at all further used by me to create a join with other tables. I want to ask how to join further? Any clue?
You need something like this:
var groups = context.MLSTN
.GroupBy(x => x.MAT_ID)
.Select(g => new
{
MAT_ID = g.Key,
MaxDate = g.Max(date => date.MT_DATE)
});
var result = context.MA
.Join(context.A,
m => m.MA_ID,
a => a.MA_ID,
(m, a) => new
{
MA = m,
A = a
})
.Join(context.SP,
x => x.MA.MAId,
sp => sp.PropertyMAId,
(x, sp) => new
{
MA = x.MA ,
A = x.A,
SP = sp
})
.Join(context.MCC,
x => x.MA.MAId,
cc => cc.MAId,
(x, cc) => new
{
MA = x.MA ,
A = x.A,
SP = x.SP,
MCC = cc
})
.Join(context.MLSTN,
x => x.MA.MAId,
t => t.MAT_ID,
(x, t) => new
{
MA = x.MA ,
A = x.A,
SP = x.SP,
MCC = x.MCC,
MLSTN = t
})
.Join(groups,
x => x.MA.MAId,
g => g.MAId,
(x, g) => new
{
MA = x.MA ,
A = x.A,
SP = x.SP,
MCC = x.MCC,
MLSTN = t,
MLSG = g
});

How can I convert SQL to LINQ-to-SQL

SELECT Cities.CityName, Customers.CustomerName, SUM(Bills.Sarees)
FROM Bills INNER JOIN
Customers ON Bills.CustomerID = Customers.CustomerID INNER JOIN
Cities ON Customers.CityID = Cities.CityID
Group by CustomerName, CityName
I have tried to make it as below.... but I am unable to insert group by clause within
var query = db.Bills.Join(db.Customers, c => c.CustomerID, p => p.CustomerID, (c, p) => new
{
c.Customer.CustomerID,
c.Customer.CustomerName,
c.Customer.City.CityName,
c.Customer.Mobile1,
c.Customer.Mobile2,
c.Customer.Telephone,
c.Customer.Email,
c.Sarees
});
Looking at your SQL, you need something like this I guess:
var query = db.Bills
.Join(db.Customers, b => b.CustomerID, c => c.CustomerID, (b, c) => new
{
b.Sarees,
c.CustomerName,
c.CityID
})
.Join(db.Cities, j => j.CityID, c => c.CityID, (j, c) => new
{
j.Sarees,
j.CustomerName,
j.CityID,
c.CityName
})
.GroupBy(o => new { o.CustomerName, o.CityName })
.Select(o => new { o.Key.CityName, o.Key.CustomerName, Sum = o.Sum(i => i.Sarees) });