Ho questo script SQL che ho bisogno di convertire in Linq per l'uso con EF Core:
SELECT
A.*, B.*
FROM
[Orders] AS A
JOIN
(SELECT TOP 1 WITH TIES *
FROM [OrderMeta]
ORDER BY ROW_NUMBER() OVER (PARTITION BY OrderId ORDER BY PostDate DESC)
) AS B ON (b.OrderId = A.OrderId)
Ecco cosa ho convertito in:
public async Task<List<GetAllOrdersResult>> AdminGetOrderList()
{
using (var db = new SoulDrawContext())
{
var query = from A in db.Orders
join B in db.OrderMeta
on A.OrderId equals B.OrderId
select new GetAllOrdersResult
{
OrderId = A.OrderId,
UserId = A.UserId,
OrderDate = A.OrderDate.ToLocalTime().ToString("yyyy-MM-dd"),
Currency = A.Currency,
Amount = A.Amount,
PaymentMethod = A.PaymentMethod,
ShipTo = A.ShipTo,
Status = B.Status,
PostDate = B.PostDate.ToLocalTime().ToString("yyyy-MM-dd hh:mm"),
RefOrderId = A.RefOrderId
};
var query1 = from a in query
group a by a.OrderId
into g
orderby g.FirstOrDefault().PostDate
select new GetAllOrdersResult
{
OrderId = g.FirstOrDefault().OrderId,
UserId = g.FirstOrDefault().UserId,
OrderDate = g.FirstOrDefault().OrderDate,
Currency = g.FirstOrDefault().Currency,
Amount = g.FirstOrDefault().Amount,
PaymentMethod = g.FirstOrDefault().PaymentMethod,
ShipTo = g.FirstOrDefault().ShipTo,
Status = g.FirstOrDefault().Status,
PostDate = g.FirstOrDefault().PostDate,
RefOrderId = g.FirstOrDefault().RefOrderId
};
return await query1.ToListAsync();
}
}
Problema:
Lo script SQL in esecuzione in SSMS funziona correttamente, la query richiede circa 32 ms per essere completata, ma la query linq per nucleo EF richiede circa 9600 ms.
Ci sono circa 2000 record nella tabella degli order
e 60.000 record nella tabella degli ordermeta
.
FARE
Come posso convertire correttamente lo script SQL in Linq? (o combinare 2 query linq?)
Come posso migliorare la velocità della query?
Prova questo sperando che risolva il tuo problema
public async Task<List<GetAllOrdersResult>> AdminGetOrderList()
{
using (var db = new SoulDrawContext())
{
var query = from A in db.Orders group A by A.OrderId into g
join B in db.OrderMeta
on g.FirstOrDefault().OrderId equals B.OrderId
select new GetAllOrdersResult
{
OrderId = g.FirstOrDefault().OrderId,
UserId = g.FirstOrDefault().UserId,
OrderDate = g.FirstOrDefault().OrderDate.ToLocalTime().ToString("yyyy-MM-dd"),
Currency = g.FirstOrDefault().Currency,
Amount = g.FirstOrDefault().Amount,
PaymentMethod = g.FirstOrDefault().PaymentMethod,
ShipTo = g.FirstOrDefault().ShipTo,
Status = B.Status,//now your B in scope so you can use Directly
PostDate = B.PostDate.ToLocalTime().ToString("yyyy-MM-dd hh:mm"),
RefOrderId = g.FirstOrDefault().RefOrderId
};
query.OrderBy(B.PostDate);
return await query.ToListAsync();
}
}