Послідовність містить більше одного елемента


110

У мене виникають проблеми із захопленням списку типу "RhsTruck" через Linq та отримання їх для відображення.

RhsTruck просто має властивості Make, Model, Serial тощо ... RhsCustomer має властивості CustomerName, CustomerAddress тощо ...

Я продовжую отримувати помилку "Послідовність містить більше одного елемента". Якісь ідеї? Чи я підходжу до цього неправильно?

public RhsCustomer GetCustomer(string customerNumber)
{
    using (RhsEbsDataContext context = new RhsEbsDataContext() )
    {
        RhsCustomer rc = (from x in context.custmasts
                          where x.kcustnum == customerNumber
                          select new RhsCustomer()
                        {
                            CustomerName = x.custname,
                            CustomerAddress = x.custadd + ", " + x.custcity
                            CustomerPhone = x.custphone,
                            CustomerFax = x.custfax
                        }).SingleOrDefault();
        return rc;
    }
}

public List<RhsTruck> GetEquipmentOwned(RhsCustomer cust)
{
    using (RhsEbsDataContext context = new RhsEbsDataContext())
    {
        var trucks = (from m in context.mkpops
                      join c in context.custmasts
                        on m.kcustnum equals c.kcustnum
                      where m.kcustnum == cust.CustomerNumber
                      select new RhsTruck
                    {
                        Make = m.kmfg,
                        Model = m.kmodel,
                        Serial = m.kserialnum,
                        EquipID = m.kserialno1,
                        IsRental = false
                    }).ToList();
        return trucks;
    }
}

protected void Page_Load(object sender, EventArgs e)
{
    string testCustNum = Page.Request.QueryString["custnum"].ToString();

    RhsCustomerRepository rcrep = new RhsCustomerRepository();
    RhsCustomer rc = rcrep.GetCustomer(testCustNum);
    List<RhsTruck> trucks = rcrep.GetEquipmentOwned(rc);

    // I want to display the List into a Gridview w/auto-generated columns
    GridViewTrucks.DataSource = trucks;
    GridViewTrucks.DataBind();   
}

1
Використовуйте функцію take <> , те ж саме з функцією агрегації SQL Top () ,.Take(1).SingleOrDefault();
Thein

Відповіді:


254

Проблема в тому, що ви використовуєте SingleOrDefault. Цей спосіб вдасться лише тоді, коли колекції містять рівно 0 або 1 елемент. Я вірю, що ви шукаєте, FirstOrDefaultщо вам вдасться, незалежно від того, скільки елементів є у колекції.


8
Кальвін, у такому випадку ти повинен прийняти цю відповідь як рішення
Деян Мілічич

24
-1 "Проблема в тому, що ви використовуєте SingleOrDefault" - з того, що я можу зібрати, ОП шукає ідентифікатор клієнта, який (я припускаю) повинен бути унікальним, отже, SingleOrDefaultнасправді більш доцільним, ніж FirstOrDefault. Крім того, це фактично спричинило більш серйозну проблему з дизайном бази даних ОП, оскільки це показує, що можна додати 2 клієнтів з однаковим ідентифікатором!
Джеймс

27
@James, ОП заявило, що моя відповідь була правильною, і виняток чітко стверджує, що колекція містить більше ніж один елемент, який заважає SingleOrDefaultніколи працювати. Правда, тут може бути кращий дизайн бази даних, але це здається більш доречним як коментар до ОП, а не -1 на відповідь.
JaredPar

9
Основною проблемою IMO є дизайн DB, оскільки він показує, що до бази даних можна додати 2 унікальних ідентифікатора клієнта. SingleOrDefaultкидає виняток, оскільки існує невідповідність між тим, що метод очікує, і тим, що він знаходить. Тож, хоча ваша відповідь зупиняє виняток, для мене це фактично не вирішує проблему, це скоріше картка "вийти з тюрми", отже -1.
Джеймс

2
Це вводить в оману! Використання для SingleOrDefaultцього потрапляє, коли ви очікуєте, що колекція матиме 0 або 1 предмет, і ви хочете перевіряти, що це відбувається кожного разу ...
Ахілл

23

SingleOrDefault метод кидає Exception якщо в послідовності є більше одного елемента.

Мабуть, ваш запит у GetCustomerпошуку знаходить більше, ніж одну відповідність. Таким чином, вам або потрібно буде уточнити запит, або, швидше за все, перевірити свої дані, щоб побачити, чому ви отримуєте кілька результатів за певним номером клієнта.


5
Use FirstOrDefault insted of SingleOrDefault..

SingleOrDefault повертає SINGLE елемент або null, якщо не знайдено жодного елемента. Якщо у вашій програмі Unumerable знайдено 2 елементи, то це кидає виняток, який ви бачите

FirstOrDefault повертає ПЕРШИЙ знайдений елемент або null, якщо не знайдено жодного елемента. тому якщо є два елементи, які відповідають вашому предикату, другий ігнорується

   public int GetPackage(int id,int emp)
           {
             int getpackages=Convert.ToInt32(EmployerSubscriptionPackage.GetAllData().Where(x
   => x.SubscriptionPackageID ==`enter code here` id && x.EmployerID==emp ).FirstOrDefault().ID);
               return getpackages;
           }

 1. var EmployerId = Convert.ToInt32(Session["EmployerId"]);
               var getpackage = GetPackage(employerSubscription.ID, EmployerId);

1

FYI ви також можете отримати цю помилку, якщо EF Migrations намагається запуститись без налаштування Db, наприклад, в тестовому проекті.

Переслідував це годинами, перш ніж я зрозумів, що це помилка в запиті, але не через запит, а тому, що саме тоді, коли Міграція запускала ноги, щоб спробувати створити Db.


0

Як вказує @Mehmet, якщо ваш результат повертає більше 1 елементу, то вам потрібно буде переглянути ваші дані, оскільки я підозрюю, що це не за дизайном, якщо у вас є клієнти, які діляться власним номером.

Але до речі, я хотів дати вам короткий огляд.

//success on 0 or 1 in the list, returns dafault() of whats in the list if 0
list.SingleOrDefault();
//success on 1 and only 1 in the list
list.Single();

//success on 0-n, returns first element in the list or default() if 0 
list.FirstOrDefault();
//success 1-n, returns the first element in the list
list.First();

//success on 0-n, returns first element in the list or default() if 0 
list.LastOrDefault();
//success 1-n, returns the last element in the list
list.Last();

для отримання додаткових виразів Linq дивіться на System.Linq.Expressions

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.