Я превращаю давнего, грубого спрока в EF, чтобы сделать его более проверяемым и обслуживаемым. Большинство из них прошло довольно хорошо, за исключением этой части здесь:
select p.idProduct from products p
where
// {some random filtering bringing us down to a manageable number of rows}
AND p.idProduct NOT IN (SELECT idProduct from productsShipped)
который я преобразовал в это:
var results = dbc.products.Where(p =>
p.warehouse == warehouse
&& p.BarConversion.Bar.BarDate > minDate
&& !dbc.productsShipped.Any(ps => ps.idInventory == p.idInventory)
//&& p.productsShipped == null
&& p.OPR.Order.Payment != null
&& !(p.OPR.Order.PaymentType == 5 &&
(p.OPR.Order.Payment.paymentStatus == null ||
p.OPR.Order.Payment.paymentStatus != "accepted"))
&& p.OPR.Order.OrderSla.expectedShipDate <= dueDateCutoff);
У меня проблема в том, что таблица productsShipped абсолютно огромна. В сыром SQL предложение where должно понимать, что ему не нужно извлекать всю таблицу productsShipped, а вместо этого извлекает только те продукты, которые относятся к предыдущему запросу. Эквивалент EF разбивает его на подзапрос и запрашивает каждую запись в таблице productsShipped, в результате чего запрос занимает более пяти минут, в отличие от пары секунд, необходимых для выполнения без этого фильтра. Я попытался добавить отношения между двумя объектами с похожими результатами.
Есть ли способ, которым я могу заставить Entity сделать правильное левое внешнее исключительное объединение, а не подзапрос или аналогичным образом улучшить производительность, или я вынужден либо принять этот удар производительности, либо толкнуть часть моей логики в труднодоступную тест sproc?