it-roy-ru.com

Последовательность содержит более одного элемента

У меня есть некоторые проблемы с захватом списка типа "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();   
}
96
Calvin

Проблема в том, что вы используете SingleOrDefault . Этот метод будет успешным только тогда, когда коллекции содержат ровно 0 или 1 элемент. Я считаю, что вы ищете FirstOrDefault , который будет успешным независимо от того, сколько элементов в коллекции.

233
JaredPar

SingleOrDefault метод генерирует Exception, если в последовательности более одного элемента. 

По-видимому, ваш запрос в GetCustomer находит более одного совпадения. Поэтому вам нужно будет либо уточнить свой запрос, либо, скорее всего, проверить свои данные, чтобы понять, почему вы получаете несколько результатов для данного номера клиента.

22
Mehmet Aras

К вашему сведению, вы также можете получить эту ошибку, если EF Migrations пытается выполнить без настроенного Db, например, в тестовом проекте.

Преследовал это в течение нескольких часов, прежде чем я понял, что это ошибка в запросе, но не из-за запроса, а потому, что это произошло, когда началась миграция, чтобы попытаться создать Db.

1
Chris Moschini
Use FirstOrDefault insted of SingleOrDefault..

SingleOrDefault возвращает элемент SINGLE или ноль, если элемент не найден. Если в вашем Enumerable найдены 2 элемента, то выдается исключение, которое вы видите.

FirstOrDefault возвращает найденный элемент FIRST или значение NULL, если элемент не найден. так что если есть 2 элемента, которые соответствуют вашему предикату, второй игнорируется

   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
Muhammad Armaghan

Как указывает @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

0
Martin Sax