Это можно сделать одним оператором, преобразовав его в таблицу поиска:
var splitTables = events.Tolookup(event => event.Closer_User_ID == null);
Это вернет последовательность из двух элементов, где каждый элемент является IGrouping<bool, EventModel>
. Key
указывает, является ли последовательность последовательностью с нулевым Closer_User_Id или нет.
Однако это выглядит довольно мистически. Мой совет - расширить LINQ новой функцией.
Эта функция принимает последовательность любого вида и предикат, который разделяет последовательность на две группы: группу, которая соответствует предикату, и группу, которая не соответствует предикату.
Таким образом, вы можете использовать функцию для разделения всех видов последовательностей IEnumerable
на две последовательности.
См. Демистифицированные методы расширения
public static IEnumerable<IGrouping<bool, TSource>> Split<TSource>(
this IEnumerable<TSource> source,
Func<TSource,bool> predicate)
{
return source.ToLookup(item => item.Condition);
}
Использование:
IEnumerable<Person> persons = ...
// divide the persons into adults and non-adults:
var result = persons.Split(person => person.IsAdult);
Результат состоит из двух элементов: один с ключом true имеет всех взрослых.
Хотя использование стало легче читать, у вас все еще есть проблема с обработкой всей последовательности, в то время как на самом деле вы можете использовать только некоторые из полученных элементов
Давайте вернем IEnumerable<KeyValuePair<bool, TSource>>
, где логическое значение указывает, соответствует элемент или нет:
public static IEnumerable<KeyValuePair<bool, TSource>> Audit<TSource>(
this IEnumerable<TSource> source,
Func<TSource,bool> predicate)
{
foreach (var sourceItem in source)
{
yield return new KeyValuePair<bool, TSource>(predicate(sourceItem, sourceItem));
}
}
Теперь вы получаете последовательность, где каждый элемент говорит, соответствует он или нет. Если вам нужно только несколько из них, остальная часть последовательности не обрабатывается:
IEnumerable<EventModel> eventModels = ...
EventModel firstOpenEvent = eventModels.Audit(event => event.Closer_User_ID == null)
.Where(splitEvent => splitEvent.Key)
.FirstOrDefault();
Где указано, что вам нужны только те проверенные объекты, которые прошли аудит (ключ имеет значение true).
Поскольку вам нужен только первый элемент, остальная часть последовательности больше не проверяется