Список клиентов с датой их самого первого заказа выдаёт InvalidOperationException

200
17 сентября 2018, 14:50

Есть классы моделей

public class Customer
{
    public string CustomerID { get; set; }
    public string CompanyName { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string Region { get; set; }
    public string PostalCode { get; set; }
    public string Country { get; set; }
    public string Phone { get; set; }
    public string Fax { get; set; }
    public Order[] Orders { get; set; }
}
public class Order
{
    public int OrderID { get; set; }
    public DateTime OrderDate { get; set; }
    public decimal Total { get; set; }
}

Необходимо получить список клиентов с датой их первого заказа(заказ с самой ранней датой для каждого клиента)

Мой запрос выглядит так:

    var customers = dataSource.Customers.Select(c => c.Orders.Min(o => o.OrderDate));

Во время исполнения получаю исключениеSystem.InvalidOperationException: Последовательность не содержит элементов

Объясните пожалуйста в чем ошибка и как сделать корректный запрос. Спасибо!

Answer 1

Как верно заметили в соседнем ответе — эта ошибка возникает когда у клиента нет заказов.

Решение зависит от того, что вы хотите получить, если у клиента нет заказов. Возвращать default(DateTime), скорее всего, в этом случае плохое решение.

Если вам не нужны те клиенты, которые не делали заказов, то их нужно предварительно отсеять:

// Странный запрос — он же возвращает коллекцию DateTime, а не Customer?
var customers = dataSource.Customers
                          .Where(c => c.Orders.Any())
                          .Select(c => c.Orders.Min(o => o.OrderDate));

Либо, если вам нужны и те клиенты, которые не делали заказов, возможно, лучше будет возвращать для них вместо даты null:

var customers = dataSource.Customers
                          .Select(c => c.Orders.Min(o => (DateTime?)o.OrderDate));
// Да, для Nullable-типов Min не падает на пустой коллекции, а возвращает null:
// https://referencesource.microsoft.com/#system.core/system/linq/Enumerable.cs,1679

Ну и, в конце концов, выбрать минимальный элемент из коллекции дешевле, чем полностью ее отсортировать, не стоит забывать об этом.

Answer 2

Ошибка в том, что если у клиента заказов нет, то и минимального заказа нет, потому Min падает. Попробуйте

var customers = dataSource
                      .Customers
                      .Select(c => c.Orders.Select(o=>o.OrderDate)
                                .OrderBy(date => date)
                                .FirstOrDeafult());

В таком виде если заказа нет, то вернется значение по умолчанию для даты.

READ ALSO
В symfony не получается сделать if is_page(current_page) проверку по странице (

В symfony не получается сделать if is_page(current_page) проверку по странице (

Не работает( Это динамическая страница и у них общий шаблон( У страниц таких общий шаблон индекс но через админку была создана страница динамическая...

212
Синхронизация времени события

Синхронизация времени события

На сайте есть события, они имеют время происшествия, надо выводить их время относительно времени пользовател, как сообщения в вк

186
Почему json_decode на данном объекте может не работать?

Почему json_decode на данном объекте может не работать?

Ниже представлен HTTP-запросМне нужно извлечь из него данные - массив с ключами cells и distance

187
Создание асинхронных задач

Создание асинхронных задач

Ни разу не работал с асинхронностью в PHPПо большей части оно и не надо, но у меня такая задача: юзер жмет кнопочку, делается запрос который...

187