我有一个List<MyClass>
,其中包含Status
和Date
字段。我想返回一个MyClass
,其中Status = X
。
问题是列表中可能有多个,在这种情况下,我想对Date
进行排序并返回最新的。
这可以在LINQ中用单个表达式完成吗?
答案 0 :(得分:3)
您可以使用lambda表达式:
var yourResult = dbo.YourList.OrderByDescending(t=>t.Date).FirstOrDefault(t=>t.Status == 'X');
答案 1 :(得分:1)
如果list
已位于内存中,请尝试以下操作:
var answer = list.Where(x => x.Status == X).OrderBy(x => x.Date).LastOrDefault();
对于Entity Framework,请尝试另一种方法:
var answer = context.Table.Where(x => x.Status == X).OrderByDescending(x => x.Date).FirstOrDefault();
答案 2 :(得分:0)
因此,您需要一个MyClass
对象和一个对象X
的序列,并且想要找到最新的MyClass
对象,该对象的Status
值等于{{ 1}}
X
尽管这行得通,但是排序不是很有效:找到第一个元素后,它将对第二,第三等进行排序,而您知道它不会使用其他元素,那么为什么对它们排序呢?如果您使用var result = myList.Where(myItem => myItem.Status == X)
.OrderByDescending(myItem => myItem.Date)
.FirstOrDefault();
,则只需枚举一次
Aggregate
这会将第一个元素放在newestItem中,并扫描列表的其余部分。如果任何nextItem包含新数据,则将该下一个项目放在newestItem中,否则不要更改newestItem。最后返回newestItem,这是您想要的最新日期。
仅当您
var result = myList.Where(...)
.Aggregate( (newestItem, nextItem) => (newestItem.Date < nextItem.Date) ?
newestItem : nextItem);
用法:
static TResult GetNewestOrDefault<TSource, TResult>(this IEnumerable<TSource> source,
Func<Tsource, DateTime> dateSelector)
{
var enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{ // at least one element; initialize newest:
TSource newestElement = enumerator.Current;
DateTime newestDate = dateSelector(newest);
// scan the rest of the sequence and check if newer:
while (enumerator.MoveNext())
{
Tsource nextElement = enumerator.Current;
Datetime nextDate = dateSelector(nextElement);
// if next element has a newer date, remember it as newest:
if (newestDate < nextDate
{
newestElement = nextElement;
newestDate = nextDate,
}
}
// scanned all elements exactly once
return newestElement;
}
else
// empty sequence, return default
return default(TResult);
}
这将扫描您的序列一次。