Is there a way I could simplify my lambda expression:
models = _context.something
.Where(i => i.Amount > 0)
.Select(o => new somemodel
{
one = (o.property.prices.Where(i => i.IsCurrent == true).FirstOrDefault().Value - o.property.prices.Where(i => i.IsCurrent == true).FirstOrDefault().Price).ToString(),
two = o.property.prices.Where(i => i.IsCurrent == true).FirstOrDefault().Price,
three = o.property.prices.Where(i => i.IsCurrent == true).FirstOrDefault().Price.ToPriceStr("£"),
four = o.property.rents.Where(i => i.IsCurrent == true).FirstOrDefault().Rent * 1200 / o.property.prices.Where(i => i.IsCurrent == true).FirstOrDefault().Price,
five = Convert.ToInt64(o.property.prices.Where(o => o.IsCurrent == true).FirstOrDefault().Value) * o.property.amount,
six = (Convert.ToInt64(o.property.prices.Where(o => o.IsCurrent == true).FirstOrDefault().Value) * o.property.amount).ToPriceStr("£"),
})
.Distinct()
.ToList();
This is just a sample the real one used the same sort of code many times. It is really prone to error as if I change it I have so many places to do it.
the code o.property.prices.Where(i => i.IsCurrent == true).FirstOrDefault()
is all over my expression. Is there a way I can write in once and reuse it.
This is where query expression comes in handy, because it allows let clauses.
models = (from o in _context.something
where o.Amount > 0
let firstCurrentPrice = o.property.prices.Where(i => i.IsCurrent).FirstOrDefault()
select new some model
{
one = (firstCurrentPrice.Value - firstCurrentPrice.Price).ToString(),
two = firstCurrentPrice.Price,
three = firstCurrentPrice.Price.ToPriceStr("£"),
four = o.property.rents.Where(i => i.IsCurrent == true).FirstOrDefault().Rent * 1200 / firstCurrentPrice.Price,
five = Convert.ToInt64(firstCurrentPrice.Value) * o.property.amount,
six = (Convert.ToInt64(firstCurrentPrice.Value) * o.property.amount).ToPriceStr("£"),
})
.Distinct()
.ToList();
My suggestion is that you add 'helper' methods to your main class
e.g. GetCurrentRent(), GetCurrentPrice(), where you encapsulate the .Where(i => i.Iscurrent).FirstOrDefault()
logic. Then in your Select
statement you just call these helper methods. This will drastically cleanup that code as well as keeping your 'logic' encapsulated in the class.
models = _context.something
.Where(i => i.Amount > 0)
.Select(o => new somemodel
{
one = (o.property.GetCurrentPrice().Value - o.property.GetCurrentPrice().Value.Price).ToString(),
two = o.property.GetCurrentPrice().Value.Price,
three = o.property.GetCurrentPrice().Value.Price.ToPriceStr("£"),
four = o.property.GetCurrentRent().Rent * 1200 / o.property.GetCurrentRent().Price,
five = Convert.ToInt64(o.property.GetCurrentPrice().Value) * o.property.amount,
six = (Convert.ToInt64(o.property.GetCurrentPrice().Value) * o.property.amount).ToPriceStr("£"),
})
.Distinct()
.ToList();
you can then take it one step further and only select the current Price and Rent as a 'tuple', and then run your logic over that:
models = _context.something
.Where(i => i.Amount > 0)
.Select(x => new { Amount = x.amount, CurrentPrice = x.GetCurrentPrice(), CurrentRent = x.GetCurrentRent() })
.Select(o => new somemodel
{
one = (o.CurrentPrice.Value - o.CurrentPrice.Value.Price).ToString(),
two = o.CurrentPrice.Value.Price,
three = o.CurrentPrice.Value.Price.ToPriceStr("£"),
four = o.CurrentRent.Rent * 1200 / o.CurrentRent.Price,
five = Convert.ToInt64(o.CurrentPrice.Value) * o.Amount,
six = (Convert.ToInt64(o.CurrentPrice.Value) * o.Amount).ToPriceStr("£"),
})
.Distinct()
.ToList();