Problém je v tom, že kontrolujete rok, město a QsNo na OutPut
proměnná po spojení... ale pokud je OutPut null (což by se stalo, kdyby v AllCosts nebyly žádné řádky), pak budou tyto kontroly vždy nepravdivé, takže pár (kód, OutPut) bude odfiltrován klauzulí where. EF tuto skutečnost detekuje a generuje dotaz, který je efektivnější pouze pomocí vnitřního spojení.
Co opravdu chcete udělat, je odfiltrovat kandidátské řádky z nákladů, spíše než filtrovat páry (kód, cena). Chcete-li to provést, můžete svůj filtr posunout nahoru, aby se vztahoval přímo na tabulku Náklady:
var Result = from code in ent.ProductCodes
join cost
in ent.Costs.Where(c => c.Year == Year && c.City == City && c.QsNo == Qsno)
on new { code.Year, code.Code } equals new { cost.Year, cost.Code }
into AllCosts
from OutPut in AllCosts.DefaultIfEmpty()
where code.PageNo == PageNo
select new
{
ProductCode = code.Code
Col6 = OutPut.Price
};