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

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
});

Related

Convert sql to linq with STRING_AGG

convert sql to linq that has STRING_AGG
SELECT
V.pkid,
V.[Name] AS VendorName,
SFTP.SFTP_Paths AS SFTP_Paths
FROM
dbo.Vendor V
LEFT OUTER JOIN (
SELECT
connected_to,
STRING_AGG(rootfolder, ', ') AS SFTP_Paths
FROM
dbo.FTP
WHERE
connected_to_type = 4 -- Vendor
GROUP BY
connected_to
) SFTP ON v.pkid = SFTP.connected_to
WHERE
V.active = 1
order by
V.[name]
This query returns the same sql query result.
Instead of STRING_AGG (rootfolder, ',') AS SFTP_Paths I used SFTP_Paths = string.Join(",", b.Select (c => c.rootfolder).ToArray()) for equivalence.
The rest of the query is understandable.
var query = vendorList.Join(lstFtp.Where(x => x.connected_to_type == 4).GroupBy(a => a.connected_to)
.Select(b => new
{
connected_to = b.Key,
SFTP_Paths = b.Select(c => c.rootfolder).ToList()
}).AsEnumerable()
.Select(b => new
{
connected_to = b.connected_to,
SFTP_Paths = string.Join(",", b.SFTP_Paths).ToArray()
}),
right => right.pkid,
left => left.connected_to,
(right, left) => new
{
V = right,
SFTP = left
}).Where(d => d.V.active == 1)
.Select(e => new
{
pkid = e.V.pkid,
VendorName = e.V.Name,
SFTP_Paths = e.SFTP.SFTP_Paths
})
.OrderBy(e => e.VendorName).ToList();

Entity Framework Join multiple tables is slow

first time I was trying to join this many tables using Entity Framework.
Everything works well but loading time is about 1 minute, very bad. I dont know if is some different solution to join this many tables, or something what could help.
It is about 5000 records in database. I think in future number of this records can be more higher. I need something what will take it. Thanks.
Code below:
var JoinedTopCars = db.CustomerAdvertisement.Where(o => o.Top == true)
.Join(
db.CarManufacturerName,
n => n.CarManufacturerId,
q => q.CarManufacturerId,
(n, q) => new
{
n,
q,
})
.Join(
db.CarManufacturerModel,
o => o.n.CarModelId,
j => j.CarModelId,
(o, j) => new
{
j,
o,
}).Where(y => y.j.CarManufacturerId == y.o.q.CarManufacturerId)
.Join(
db.TypeOFFuel,
e => e.o.n.FuelId,
r => r.Id,
(e, r) => new
{
e,
r,
})
.Join(
db.TypeOFGearBox,
t => t.e.o.n.GearBoxId,
i => i.Id,
(t, i) => new
{
t,
i,
})
.Join(
db.Country,
y => y.t.e.o.n.CountryOfOrigin,
u => u.Id,
(y, u) => new
{
y,
u,
})
.Join(
db.TypeOFChassis,
c => c.y.t.e.o.n.ChassisId,
d => d.Id,
(c, d) => new
{
c,
d,
})
.Join(
db.CarDoors,
e => e.c.y.t.e.o.n.CarDoorsId,
f => f.Id,
(e, f) => new
{
e,
f,
})
.Join(
db.TypOfMovement,
g => g.e.c.y.t.e.o.n.MovementId,
f => f.Id,
(g, f) => new
{
g,
f,
})
.Join(
db.Area,
i => i.g.e.c.y.t.e.o.n.AreaOfOrigin ?? 0,
f => f.Id,
(i, f) => new
{
i,
f,
})
.Join(
db.District,
j => j.i.g.e.c.y.t.e.o.n.OkresOfOrigin ?? 0,
f => f.Id,
(j, f) => new
{
j,
f,
})
.Join(
db.CarColor,
k => k.j.i.g.e.c.y.t.e.o.n.CarColorId,
x => x.Id,
(k, x) => new JoinedTopCars
{
Id = k.j.i.g.e.c.y.t.e.o.n.Id,
Objem = k.j.i.g.e.c.y.t.e.o.n.cm3,
Carname = k.j.i.g.e.c.y.t.e.o.q.CarName,
CarModel = k.j.i.g.e.c.y.t.e.j.CarModel,
Typ = k.j.i.g.e.c.y.t.e.o.n.ModelType,
Color = x.ColorName,
Karoseria = k.j.i.g.e.d.ChassisName,
Dvere = k.j.i.g.f.NumberOfDoors,
Pohon = k.j.i.f.Movement,
VIN = k.j.i.g.e.c.y.t.e.o.n.VIN,
Metalic = k.j.i.g.e.c.y.t.e.o.n.Metalic,
Poskodene = k.j.i.g.e.c.y.t.e.o.n.Crashed,
Pojazdne = k.j.i.g.e.c.y.t.e.o.n.Drivable,
DPH = k.j.i.g.e.c.y.t.e.o.n.DPH,
Leasing = k.j.i.g.e.c.y.t.e.o.n.Leasing,
Emisie = k.j.i.g.e.c.y.t.e.o.n.Emmisions,
Spotreba = k.j.i.g.e.c.y.t.e.o.n.Consumption,
Km = k.j.i.g.e.c.y.t.e.o.n.KM,
Rok = k.j.i.g.e.c.y.t.e.o.n.DateOfOrigin.ToString(),
Vykon = k.j.i.g.e.c.y.t.e.o.n.HP,
Palivo = k.j.i.g.e.c.y.t.r.Fuel,
Prevodovka = k.j.i.g.e.c.y.i.GearBox,
Krajina = k.j.i.g.e.c.u.CountryName,
Okres = k.f.DistrictName,
Kraj = k.j.f.AreaName,
Vybava = k.j.i.g.e.c.y.t.e.o.n.Equipment,
Popis = k.j.i.g.e.c.y.t.e.o.n.Description,
Kontakt = k.j.i.g.e.c.y.t.e.o.n.ContInfo,
ZobrazMeno = k.j.i.g.e.c.y.t.e.o.n.ShowName,
ZobrazCislo = k.j.i.g.e.c.y.t.e.o.n.ShowPhone,
Cena = k.j.i.g.e.c.y.t.e.o.n.Price,
TitleImage = k.j.i.g.e.c.y.t.e.o.n.TitlePhoto,
})
.OrderByDescending(z => z.Id)
.Take(15);
EDIT: I make what #romfir write bellow and decrase loading time from 1 minute to 3 sec.
Create SQL view
insert SQL query with JOINed tables (if you expect empty value use LEFT JOIN)
Update ADO.NET EF model, .edmx file
use this SQL View simmilar like table
You can try to create View in the database, like this:
CREATE VIEW my_view_name
AS
SELECT
CustomerAdvertisement.ID as CustomerAdvertisementID -- 'as Name' is optional
CustomerAdvertisement.cm3
-- other columns You want to include
FROM
CustomerAdvertisement
JOIN CarManufacturerName
on CarManufacturerName.CarManufacturerId = CustomerAdvertisement.CarManufacturerId
JOIN SomeTable
on some_condition
-- other joins
WHERE
CustomerAdvertisement.Top = true
and other_conditions
After creating view that matches Your criteria, You can scaffold it, and then use in Your code.

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();

Convert SQL Server query to Linq query

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
;

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) });