我有这个简单的课程:
public class JDEItemLotAvailability
{
public string Code { get; set; }
public int ShortCode { get; set; }
public string Description { get; set; }
public string PrimaryUnitCode { get; set; }
public string BranchPlant { get; set; }
public string Location { get; set; }
public string Lot { get; set; }
public int AvailableQuantity { get; set; }
}
我的BLL中的这个DAL方法返回它们的列表:
var returnedLotList = _JDE8dal.GetLotAvailabilityAsList(_lot);
我想在返回的列表中执行以下操作,并且我希望以最“优雅”的LINQ方式执行此操作。
我想检查列表中是否有符合特定条件的记录。我想到过这样的事情:
var query =
returnedLotList.Where(l => l.AvailableQuantity != 0 && l.BranchPlant == _mcu && l.Location == _locn)
.OrderByDescending(l => l.AvailableQuantity);
但我想说,如果上面的查询没有返回结果,我想采取其余列表条目的第一个。
我该怎么做?
答案 0 :(得分:3)
您可以使用DefaultIfEmpty
//your first query, unaltered
var query =
returnedLotList.Where(l => l.AvailableQuantity != 0 && l.BranchPlant == _mcu && l.Location == _locn)
.OrderByDescending(l => l.AvailableQuantity);
var query2 = query.DefaultIfEmpty(returnedLotList.Take(1));
答案 1 :(得分:0)
您可以制作一个执行此操作的扩展方法:
public static IEnumerable<T> WhereOrFirstOfRest<T>(
this IEnumerable<T> collection, Func<T, bool> predicate)
{
var filtered = collection.Where(predicate);
return filtered.Any() ? filtered : collection.Take(1);
}
此扩展方法的缺点是它多次迭代集合。当您处理流(例如,来自数据库)时,这可能是一个问题。一种更有效的方法如下:
public static IEnumerable<T> WhereOrFirstOfRest<T>(
this IEnumerable<T> collection, Func<T, bool> predicate)
{
// Materialize the complete collection.
collection = collection.ToArray();
// Filter the collection. ToArray prevents calling the predicate
// twice for any item.
var filtered = collection.Where(predicate).ToArray();
return filtered.Any() ? filtered : collection.Take(1);
}
虽然这可以节省您对数据库的任何可能的额外调用,但这确实会在封面下创建几个新数组。因此,最有效的方法如下:
public static IEnumerable<T> WhereOrFirstOfRest<T>(
this IEnumerable<T> collection, Func<T, bool> predicate)
{
T firstItem = default(T);
bool firstStored = false;
bool predicateReturnedItems = false;
foreach (var item in collection)
{
if (!firstStored)
{
firstItem = item;
firstStored = true;
}
if (predicate(item))
{
yield return item;
predicateReturnedItems = true;
}
}
if (!predicateReturnedItems && !first)
{
yield return firstItem;
}
}
答案 2 :(得分:0)
我不确定我理解但也许是这样的:
var firstMatch = returnedLotList.FirstOrDefault(l => l.AvailableQuantity != 0 &&
l.BranchPlant == _mcu &&
l.Location == _locn);
if (firstMatch != null)
return firstMatch;
int max = returnedLotList.Max(l => l.AvailableQuantity);
return returnedLotList.First(l => l.AvailableQuantity == max);