When you use OrderBy
it creates new, ordered copy of source sequence in memory (and enumerates source one more time). If you want to avoid this, you can use MoreLINQ MinBy (available from NuGet)
cOrderItem oItem = OrderItems
.Where(p => p.CategoryID == catID && !p.n_IsOfferApplied)
.MinBy(p => p.OrderItemPrice);
NOTE: it will throw exception if there is no matching items, so you can use your own extension to return default value if it is possible that no matches will be found:
public static T MinBy<T, TKey>(
this IEnumerable<T> source, Func<T, TKey> selector)
{
// throw if source or selector is null
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
return default(T);
var min = iterator.Current;
var minKey = selector(min);
IComparer<TKey> comparer = Comparer<TKey>.Default;
while (iterator.MoveNext())
{
var current = iterator.Current;
var currentKey = selector(current);
if (comparer.Compare(currentKey, minKey) < 0)
{
min = current;
minKey = currentKey;
}
}
return min;
}
}