Вы можете предотвратить повторение длинных выражений в запросах LINQ, используя синтаксис запроса с предложением let
. Это похоже на объявление переменных, которые содержат результат выражения. В вашем запросе повторяются две части, которые могут быть зафиксированы в let
переменных:
var promos = await (
from p in this._context.SinglePromotions
.Include(p => p.Rewards)
.Include(p => p.InAppProduct)
.Include(p => p.PlayerSinglePromotions)
.ThenInclude(sp => sp.Player)
.ThenInclude(pl => pl.Purchases)
let pspNotOfPlayer = p.PlayerSinglePromotions.All(sp => sp.PlayerID != Player.ID)
let firstPromotion = p.PlayerSinglePromotions.FirstOrDefault(sp => sp.PlayerID == Player.ID)
where
p.MinimumPlayerLevel <= Player.Level
&& p.Placement == placement
&& p.IsActive
&& pspNotOfPlayer || firstPromotion.PurchaseAmount < p.PurchaseLimit
&& pspNotOfPlayer || firstPromotion.Player.Purchases.Count <= p.MaxInAppPurchasesByPlayer
select p
)
.ToListAsync();
Во многих случаях это не только сделает код более читабельным, но и улучшит сгенерированный SQL, поскольку повторяющиеся подзапросы могут быть заменены предложениями CROSS APPLY
.